*/}}
Browse Source

Depletion speed etc

YimingWu 9 hours ago
parent
commit
ed5901001c
5 changed files with 124 additions and 28 deletions
  1. 16 5
      ournodes.c
  2. 96 19
      ouroperations.c
  3. 7 2
      ourpaint.h
  4. 2 1
      ourtranslations_es-ES.c
  5. 3 1
      ourtranslations_zh-hans.c

+ 16 - 5
ournodes.c

@@ -50,6 +50,7 @@ void IDN_BrushSettingsInit(OurBrushSettingsNode* n, int NoCreate){
     if(!n->Gunkyness) n->Gunkyness=laCreateOutSocket(n,"GUNKY",LA_PROP_FLOAT);
     if(!n->Force) n->Force=laCreateOutSocket(n,"FORCE",LA_PROP_FLOAT);
     if(!n->Accumulation) n->Accumulation=laCreateOutSocket(n,"ACCUM",LA_PROP_FLOAT);
+    if(!n->DepletionSpeed) n->DepletionSpeed=laCreateOutSocket(n,"DRAIN",LA_PROP_FLOAT);
     n->CanvasScale->Data=&n->rCanvasScale;
     n->Size->Data=&n->rSize;
     n->Transparency->Data=&n->rTransparency;
@@ -61,8 +62,9 @@ void IDN_BrushSettingsInit(OurBrushSettingsNode* n, int NoCreate){
     n->Angle->Data=&n->rAngle;
     n->Color->Data=Our->CurrentColor; n->Color->ArrLen=3;
     n->Gunkyness->Data=&n->rGunkyness;
-    n->Accumulation->Data=&n->rAccumulation;
     n->Force->Data=&n->rForce;
+    n->Accumulation->Data=&n->rAccumulation;
+    n->DepletionSpeed->Data=&n->rDepletionSpeed;
     n->Iteration->Data=&n->rIteration;
     n->Custom1->Data=&n->rCustom1;
     n->Custom2->Data=&n->rCustom2;
@@ -71,7 +73,7 @@ void IDN_BrushSettingsDestroy(OurBrushSettingsNode* n){
     laDestroyOutSocket(n->Size); laDestroyOutSocket(n->Transparency); laDestroyOutSocket(n->Hardness); laDestroyOutSocket(n->Smudge);
     laDestroyOutSocket(n->SmudgeLength); laDestroyOutSocket(n->DabsPerSize); laDestroyOutSocket(n->Slender); laDestroyOutSocket(n->Angle);
     laDestroyOutSocket(n->CanvasScale); laDestroyOutSocket(n->Iteration); laDestroyOutSocket(n->Custom1); laDestroyOutSocket(n->Custom2);
-    laDestroyOutSocket(n->Gunkyness); laDestroyOutSocket(n->Force); laDestroyOutSocket(n->Accumulation);
+    laDestroyOutSocket(n->Gunkyness); laDestroyOutSocket(n->Force); laDestroyOutSocket(n->Accumulation);  laDestroyOutSocket(n->DepletionSpeed);
     strSafeDestroy(&n->Base.Name);
 }
 int IDN_BrushSettingsVisit(OurBrushSettingsNode* n, laNodeVisitInfo* vi){
@@ -90,8 +92,9 @@ int IDN_BrushSettingsEval(OurBrushSettingsNode* n){
     n->rSlender = Our->CurrentBrush->Slender;
     n->rAngle = Our->CurrentBrush->Angle;
     n->rGunkyness = Our->CurrentBrush->Gunkyness;
-    n->rAccumulation = Our->CurrentBrush->Accumulation;
     n->rForce = Our->CurrentBrush->Force;
+    n->rAccumulation = Our->CurrentBrush->Accumulation;
+    n->rDepletionSpeed = Our->CurrentBrush->DepletionSpeed;
     n->rIteration = Our->CurrentBrush->Iteration;
     n->rCustom1 = Our->CurrentBrush->Custom1;
     n->rCustom2 = Our->CurrentBrush->Custom2;
@@ -107,6 +110,7 @@ void IDN_BrushSettingsCopy(OurBrushSettingsNode* new, OurBrushSettingsNode* old,
     LA_IDN_OLD_DUPL(Smudge)      LA_IDN_OLD_DUPL(SmudgeLength)
     LA_IDN_OLD_DUPL(Transparency)LA_IDN_OLD_DUPL(Gunkyness)
     LA_IDN_OLD_DUPL(Force)       LA_IDN_OLD_DUPL(Accumulation)
+    LA_IDN_OLD_DUPL(DepletionSpeed)
 }
 void ui_BrushSettingsNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laColumn *UNUSED, int context){
     laColumn* c=laFirstColumn(uil); OurBrushSettingsNode*n=This->EndInstance;
@@ -132,6 +136,7 @@ void ui_BrushSettingsNode(laUiList *uil, laPropPack *This, laPropPack *Extra, la
         laShowNodeSocket(uil,c,This,"gunkyness",0)->Flags|=LA_UI_SOCKET_LABEL_W;
         laShowNodeSocket(uil,c,This,"force",0)->Flags|=LA_UI_SOCKET_LABEL_W;
         laShowNodeSocket(uil,c,This,"accumulation",0)->Flags|=LA_UI_SOCKET_LABEL_W;
+        laShowNodeSocket(uil,c,This,"draining_speed",0)->Flags|=LA_UI_SOCKET_LABEL_W;
     laEndRow(uil,b);
     b=laBeginRow(uil,c,0,0); u=laShowLabel(uil,c,"Canvas Scale",0,0);u->Flags|=LA_TEXT_ALIGN_RIGHT; u->Expand=1;  laShowNodeSocket(uil,c,This,"canvas_scale",0);
         u=laShowLabel(uil,c,"Dabs Per Size",0,0);u->Flags|=LA_TEXT_ALIGN_RIGHT; u->Expand=1; laShowNodeSocket(uil,c,This,"dabs_per_size",0); laEndRow(uil,b);
@@ -163,6 +168,7 @@ void IDN_BrushOutputsInit(OurBrushOutputsNode* n, int NoCreate){
     if(!n->Gunkyness) n->Gunkyness=laCreateInSocket("GUNKY",LA_PROP_FLOAT);
     if(!n->Force) n->Force=laCreateInSocket("FORCE",LA_PROP_FLOAT);
     if(!n->Accumulation) n->Accumulation=laCreateInSocket("ACCUM",LA_PROP_FLOAT);
+    if(!n->DepletionSpeed) n->DepletionSpeed=laCreateInSocket("DRAIN",LA_PROP_FLOAT);
     strSafeSet(&n->Base.Name, "Brush Outputs");
 }
 void IDN_BrushOutputsDestroy(OurBrushOutputsNode* n){
@@ -170,7 +176,7 @@ void IDN_BrushOutputsDestroy(OurBrushOutputsNode* n){
     laDestroyInSocket(n->Size); laDestroyInSocket(n->Transparency); laDestroyInSocket(n->Hardness); laDestroyInSocket(n->Smudge);
     laDestroyInSocket(n->SmudgeLength); laDestroyInSocket(n->DabsPerSize); laDestroyInSocket(n->Slender); laDestroyInSocket(n->Angle);
     laDestroyInSocket(n->Color); laDestroyInSocket(n->Repeats); laDestroyInSocket(n->Discard);
-    laDestroyInSocket(n->Gunkyness); laDestroyInSocket(n->Force); laDestroyInSocket(n->Accumulation);
+    laDestroyInSocket(n->Gunkyness); laDestroyInSocket(n->Force); laDestroyInSocket(n->Accumulation); laDestroyInSocket(n->DepletionSpeed);
     strSafeDestroy(&n->Base.Name);
 }
 int IDN_BrushOutputsVisit(OurBrushOutputsNode* n, laNodeVisitInfo* vi){
@@ -182,6 +188,7 @@ int IDN_BrushOutputsVisit(OurBrushOutputsNode* n, laNodeVisitInfo* vi){
     BRUSH_OUT_VISIT(DabsPerSize) BRUSH_OUT_VISIT(Slender) BRUSH_OUT_VISIT(Angle)
     BRUSH_OUT_VISIT(Color) BRUSH_OUT_VISIT(Repeats) BRUSH_OUT_VISIT(Discard)
     BRUSH_OUT_VISIT(Gunkyness) BRUSH_OUT_VISIT(Force) BRUSH_OUT_VISIT(Accumulation)
+    BRUSH_OUT_VISIT(DepletionSpeed)
 #undef BRUSH_OUT_VISIT
     LA_ADD_THIS_NODE(n,vi);
     return LA_DAG_FLAG_PERM;
@@ -213,6 +220,7 @@ int IDN_BrushOutputsEval(OurBrushOutputsNode* n){
     BRUSH_OUT_EVAL(Gunkyness)
     BRUSH_OUT_EVAL(Force)
     BRUSH_OUT_EVAL(Accumulation)
+    BRUSH_OUT_EVAL(DepletionSpeed)
     BRUSH_OUT_EVAL(Repeats)
     BRUSH_OUT_EVAL(Discard)
 #undef BRUSH_OUT_EVAL
@@ -223,7 +231,7 @@ void IDN_BrushOutputsCopy(OurBrushOutputsNode* new, OurBrushOutputsNode* old, in
         LA_IDN_NEW_LINK(Offset) LA_IDN_NEW_LINK(Size) LA_IDN_NEW_LINK(Transparency) LA_IDN_NEW_LINK(Hardness)
         LA_IDN_NEW_LINK(Smudge) LA_IDN_NEW_LINK(SmudgeLength) LA_IDN_NEW_LINK(DabsPerSize) LA_IDN_NEW_LINK(Slender)
         LA_IDN_NEW_LINK(Angle) LA_IDN_NEW_LINK(Color) LA_IDN_NEW_LINK(Repeats) LA_IDN_NEW_LINK(Discard)
-        LA_IDN_NEW_LINK(Gunkyness) LA_IDN_NEW_LINK(Force) LA_IDN_NEW_LINK(Accumulation)
+        LA_IDN_NEW_LINK(Gunkyness) LA_IDN_NEW_LINK(Force) LA_IDN_NEW_LINK(Accumulation) LA_IDN_NEW_LINK(DepletionSpeed)
         return;
     }
     return;
@@ -250,6 +258,7 @@ void ui_BrushOutputsNode(laUiList *uil, laPropPack *This, laPropPack *Extra, laC
         laShowNodeSocket(uil,c,This,"gunkyness",0)->Flags|=LA_UI_SOCKET_LABEL_E;
         laShowNodeSocket(uil,c,This,"force",0)->Flags|=LA_UI_SOCKET_LABEL_E;
         laShowNodeSocket(uil,c,This,"accumulation",0)->Flags|=LA_UI_SOCKET_LABEL_E;
+        laShowNodeSocket(uil,c,This,"draining_speed",0)->Flags|=LA_UI_SOCKET_LABEL_E;
     laEndRow(uil,b);
     b=laBeginRow(uil,c,0,0); laShowNodeSocket(uil,c,This,"dabs_per_size",0); laShowLabel(uil,c,"Dabs Per Size",0,0); laEndRow(uil,b);
     b=laBeginRow(uil,c,0,0);
@@ -357,6 +366,7 @@ void ourRegisterNodes(){
     laAddSubGroup(pc,"gunkyness", "Gunkyness","Gunkyness","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Gunkyness),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     laAddSubGroup(pc,"force", "Force","Force","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Force),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     laAddSubGroup(pc,"accumulation", "Accumulation","Accumulation","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Accumulation),0,0,0,0,0,0,0,LA_UDF_SINGLE);
+    laAddSubGroup(pc,"draining_speed", "Depletion Speed","Depletion Speed","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,DepletionSpeed),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     laAddSubGroup(pc,"iteration", "Iteration","Iteration","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Iteration),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     laAddSubGroup(pc,"c1", "C1","Custom 1","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Custom1),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     laAddSubGroup(pc,"c2", "C2","Custom 2","la_out_socket",0,0,0,offsetof(OurBrushSettingsNode,Custom2),0,0,0,0,0,0,0,LA_UDF_SINGLE);
@@ -376,6 +386,7 @@ void ourRegisterNodes(){
     laAddSubGroup(pc,"gunkyness", "Gunkyness","Gunkyness","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Gunkyness),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     laAddSubGroup(pc,"force", "Force","Force","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Force),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     laAddSubGroup(pc,"accumulation", "Accumulation","Accumulation","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Accumulation),0,0,0,0,0,0,0,LA_UDF_SINGLE);
+    laAddSubGroup(pc,"draining_speed", "Depletion Speed","Depletion Speed","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,DepletionSpeed),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     laAddSubGroup(pc,"color", "Color","Color","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Color),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     laAddSubGroup(pc,"repeats", "Repeats","Repeats","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Repeats),0,0,0,0,0,0,0,LA_UDF_SINGLE);
     laAddSubGroup(pc,"discard", "Discard","Discard","la_in_socket",0,0,0,offsetof(OurBrushOutputsNode,Discard),0,0,0,0,0,0,0,LA_UDF_SINGLE);

+ 96 - 19
ouroperations.c

@@ -31,12 +31,15 @@ extern tnsMain* T;
 
 laWidget _OUR_WIDGET_PIGMENT_MIXER={0};
 laWidget _OUR_WIDGET_PIGMENT_PREVIEW={0};
+laWidget _OUR_WIDGET_PIGMENT_LOADER={0};
 laWidget _OUR_WIDGET_COLOR_PAD={0};
 laWidget* OUR_WIDGET_PIGMENT_MIXER=&_OUR_WIDGET_PIGMENT_MIXER;
 laWidget* OUR_WIDGET_PIGMENT_PREVIEW=&_OUR_WIDGET_PIGMENT_PREVIEW;
+laWidget* OUR_WIDGET_PIGMENT_LOADER=&_OUR_WIDGET_PIGMENT_LOADER;
 laWidget *OUR_WIDGET_COLOR_PAD=&_OUR_WIDGET_COLOR_PAD;
 laUiType* _OUR_UI_PIGMENT_MIXER;
 laUiType* _OUR_UI_PIGMENT_PREVIEW;
+laUiType* _OUR_UI_PIGMENT_LOADER;
 laUiType* _OUR_UI_COLOR_PAD;
 
 OurPigmentData _OUR_PIGMENT_D65={{0.574,0.703,0.916,1.000,0.974,0.923,0.923,0.877,0.832,0.877,0.794,0.737,0.716,0.730,0.718,1.000},{0},{0}};
@@ -524,6 +527,7 @@ void ourui_ToolsPanel(laUiList *uil, laPropPack *This, laPropPack *DetachedProps
             laShowItem(uil,c,&cb->PP,"smudge_resample_length");
             laShowItem(uil,c,&cb->PP,"gunkyness");
             OUR_BR laShowItem(uil,c,&cb->PP,"force")->Expand=1; OUR_PRESSURE("pressure_force") OUR_ER
+            OUR_BR laShowItem(uil,c,&cb->PP,"depletion_speed")->Expand=1;  OUR_PRESSURE("pressure_depletion") OUR_ER
 
             laUiItem*badv=laOnConditionToggle(uil,c,0,0,0,0,0);{ strSafeSet(&badv->ExtraInstructions,"text=Advanced...");
                 laShowSeparator(uil,c);
@@ -635,6 +639,7 @@ void ourui_ColorPanel(laUiList *uil, laPropPack *This, laPropPack *DetachedProps
     laColumn *cll=laLeftColumn(cl,0),*clr=laRightColumn(cl,0);
 
     laUiItem* pigb=laOnConditionThat(uil,c,laPropExpression(0,"our.canvas.pigment_mode"));{
+        laShowItemFull(uil,cl,0,"our.tools.current_brush.pigment_loading",OUR_WIDGET_PIGMENT_LOADER,0,0,0);
         laUiItem* mixui=laShowItemFull(uil,cl,0,"our.mixed_pigment",OUR_WIDGET_PIGMENT_MIXER,0,0,0); mixui->Extent=4;
         laUiItem* bc=laOnConditionThat(uil,cll,laAnd(laPropExpression(0,"our.canvas.set_use_white"),laNot(laPropExpression(0,"our.preferences.reorder_pigments"))));{
             laShowItemFull(uil,cll,0,"our.canvas.use_white",LA_WIDGET_COLLECTION_SINGLE,0,ourui_PigmentOnlyPad,0)
@@ -678,6 +683,7 @@ void ourui_ColorPanel(laUiList *uil, laPropPack *This, laPropPack *DetachedProps
         b=laOnConditionThat(uil,c,laEqual(laPropExpression(0,"our.canvas.color_interpretation"),laIntExpression(OUR_CANVAS_INTERPRETATION_D65_P3)));{
             laShowItemFull(uil,c,0,"our.current_color",LA_WIDGET_FLOAT_COLOR_HCY,0,0,0)->Flags|=LA_UI_FLAGS_COLOR_SPACE_D65_P3|LA_UI_FLAGS_NO_CONFIRM;
         }laEndCondition(uil,b);
+        laShowItemFull(uil,c,0,"our.tools.current_brush.pigment_loading",OUR_WIDGET_PIGMENT_LOADER,0,0,0);
         b=laBeginRow(uil,c,0,0);
         uishowpalette=laShowItemFull(uil,cl,0,"our.preferences.palette_in_colors_panel",LA_WIDGET_ENUM_HIGHLIGHT,"text=Show Palette",0,0); uishowpalette->Expand=1;
         laUiItem* uispect=laShowItem(uil,c,0,"our.preferences.spectral_mode"); uispect->Flags|=LA_UI_FLAGS_NO_CONFIRM; uispect->Expand=1;
@@ -790,6 +796,7 @@ void ourui_OurPreference(laUiList *uil, laPropPack *This, laPropPack *DetachedPr
     laShowItem(uil,cr,0,"our.preferences.bad_event_tolerance");
     laShowItem(uil,cr,0,"our.preferences.smoothness");
     laShowItem(uil,cr,0,"our.preferences.hardness");
+    laShowItem(uil,cr,0,"our.preferences.mixing_speed");
 
     laShowSeparator(uil,c);
 
@@ -1557,6 +1564,52 @@ void our_ColorPadDraw(laUiItem *ui, int h){
     tnsColor4dv(laThemeColor(bt,LA_BT_BORDER)); la_DrawBorder(ui->L,ui->R,ui->U,ui->B);
 }
 
+int ourmod_PigmentLoader(laOperator* a, laEvent* e){
+    laUiItem *ui = a->Instance;
+    laBoxedTheme *bt = (*ui->Type->Theme);
+
+    if (!laIsInUiItem(ui, a, e->x, e->y) && ui->State==LA_UI_NORMAL){
+        return LA_FINISHED_PASS;
+    }
+
+    OurBrush*b=ui->PP.LastPs?ui->PP.LastPs->UseInstance:0;
+    if(!b){ return LA_RUNNING; }
+
+    if(e->type==LA_L_MOUSE_DOWN){ ui->State=LA_UI_ACTIVE; }
+    if(ui->State==LA_UI_ACTIVE && (e->type&LA_MOUSE_EVENT)){
+        if(e->type==LA_L_MOUSE_UP || e->type==LA_R_MOUSE_DOWN){ ui->State=LA_UI_NORMAL; laRedrawCurrentPanel(); return LA_RUNNING; }
+        real fac=(1.0f-OUR_MIXING_SPEED)*e->Pressure; b->PigmentLoading=1.0f-(1.0f-b->PigmentLoading)*fac; laNotifyUsersPP(&ui->PP);
+    }
+
+    return LA_RUNNING;
+}
+void our_PigmentLoaderDraw(laUiItem *ui, int h){
+    laBoxedTheme *bt = (*ui->Type->Theme);
+    OurBrush*b=ui->PP.LastPs?ui->PP.LastPs->UseInstance:0;
+    real UseColor[4]; UseColor[3]=0.3;
+    real* color;
+    if(Our->PigmentMode){ color=Our->MixedPigment.PreviewColor[0]; }
+    else{ color=Our->CurrentColor; } tnsVectorSet3v(UseColor,color);
+    
+    int L=ui->L,R=ui->R,U=ui->U,B=ui->B;
+
+    int sw=la_GetBoxOffset(bt,ui->State);
+    tnsUseNoTexture();
+    la_DrawBoxAutoFill(ui->L,ui->R,ui->U,ui->B,bt,ui->State,UseColor);
+
+    if (b){
+        int R1=tnsInterpolate(L,R,b->PigmentLoading);
+        tnsColor4d(LA_COLOR3(color),1.0);
+        tnsVertex2d(L-sw, U-sw); tnsVertex2d(R1-sw, U-sw);
+        tnsVertex2d(R1-sw, B-sw); tnsVertex2d(L-sw, B-sw);
+        tnsPackAs(GL_TRIANGLE_FAN);
+    }
+
+    la_DrawBoxAutoBorder(ui->L,ui->R,ui->U,ui->B,bt,ui->State);
+
+}
+
+
 int our_PigmentMixerDetectPosition(laUiItem* ui, int x, int y){
     int h = (ui->B-ui->U)/2; if(h>LA_RH) h=LA_RH; h+=ui->U;
     if(y<h){ int middle = (ui->R-ui->L)/2; if(x<=middle) return 2; return 3; }
@@ -1579,14 +1632,21 @@ int ourmod_PigmentMixer(laOperator* a, laEvent* e){
         if(e->type==LA_L_MOUSE_DOWN){
             es->On=our_PigmentMixerDetectPosition(ui,e->x,e->y);
             if(es->On==4){ es->LastX=e->x;es->LastY=e->y;es->TargetVali=ui->Extent; es->Dragging=1; }
-            if(es->On==2){ our_PigmentClear(pd); laNotifyUsers("our.mixed_pigment"); return LA_RUNNING;  }
+            elif(es->On==2){ our_PigmentClear(pd); laNotifyUsers("our.mixed_pigment"); return LA_RUNNING;  }
+            elif(es->On==1){ if(Our->CurrentBrush) ui->State=LA_UI_ACTIVE; }
         }
     }
     if(es->On){
-        if(e->type==LA_L_MOUSE_UP || (e->type==LA_KEY_DOWN && e->key==LA_KEY_ESCAPE)){ ui->Extra->On=0; es->Dragging=0; return LA_RUNNING; }
+        if(e->type==LA_L_MOUSE_UP || (e->type==LA_KEY_DOWN && e->key==LA_KEY_ESCAPE)){
+            ui->Extra->On=0; es->Dragging=0; laRedrawCurrentPanel(); ui->State=LA_UI_NORMAL; return LA_RUNNING;
+        }
         if(es->On==3){ our_PigmentMix(&Our->MixedPigment,OUR_PIGMENT_WATER,OUR_MIXING_SPEED*e->Pressure);
             our_PigmentToPreviewSelf(&Our->MixedPigment); laNotifyUsers("our.mixed_pigment"); }
-        if(es->On==4){ int d=e->y-es->LastY; int h=es->TargetVali+d/LA_RH; if(h<2){ h=2; } if(ui->Extent!=h){ ui->Extent=h; laRecalcCurrentPanel(); };  }
+        elif(es->On==4){ int d=e->y-es->LastY; int h=es->TargetVali+d/LA_RH; if(h<2){ h=2; } if(ui->Extent!=h){ ui->Extent=h; laRecalcCurrentPanel(); };  }
+        elif(es->On==1 && e->type&LA_MOUSE_EVENT){ OurBrush* b=Our->CurrentBrush; if(!b){ return LA_RUNNING; }
+            real fac=(1.0f-OUR_MIXING_SPEED)*e->Pressure; b->PigmentLoading=1.0f-(1.0f-b->PigmentLoading)*fac; laNotifyUsers("our.tools.current_brush.pigment_loading");
+            laRedrawCurrentPanel(); es->TargetValf=e->Pressure;
+        }
     }
 
     return LA_RUNNING;
@@ -1594,21 +1654,24 @@ int ourmod_PigmentMixer(laOperator* a, laEvent* e){
 void our_PigmentMixerDraw(laUiItem* ui, int h){
     laBoxedTheme *bt = (*ui->Type->Theme);
     OurPigmentData* pd=ui->PP.EndInstance;
+    laGeneralUiExtraData *es = ui->Extra;
     tnsUseNoTexture();
+    int L=ui->L,R=ui->R,U=ui->U,B=ui->B;
+    if(ui->State==LA_UI_ACTIVE){ int sw=LA_SHADOW_W*es->TargetValf; L+=sw;R+=sw;U+=sw;B+=sw; }
 
-    our_PigmentDrawPreview(ui->L,ui->R,ui->U,ui->B,pd,bt);
+    our_PigmentDrawPreview(L,R,U,B,pd,bt);
 
     real bkg[4]; tnsVectorCopy4d(laThemeColor(bt,LA_BT_NORMAL),bkg);
-    tnsColor4d(LA_COLOR3(bkg),bkg[3]*0.5); la_DrawBox(ui->L,ui->R,ui->U,ui->U+LA_RH);
-    tnsColor4dv(laThemeColor(bt,LA_BT_BORDER)); la_DrawBorder(ui->L,ui->R,ui->U,ui->B);
+    tnsColor4d(LA_COLOR3(bkg),bkg[3]*0.5); la_DrawBox(L,R,U,U+LA_RH);
+    tnsColor4dv(laThemeColor(bt,LA_BT_BORDER)); la_DrawBorder(L,R,U,B);
 
     int middle=(ui->R+ui->L)/2;
 
-    tnsDrawStringAuto(transLate("🧹 Clear"),laThemeColor(bt,LA_BT_TEXT),ui->L+LA_M,middle-LA_M,ui->U,LA_TEXT_ALIGN_LEFT|LA_TEXT_SHADOW);
-    tnsDrawStringAuto(transLate("Water 💦"),laThemeColor(bt,LA_BT_TEXT),middle+LA_M,ui->R-LA_M,ui->U,LA_TEXT_ALIGN_RIGHT|LA_TEXT_SHADOW);
-    tnsDrawStringAuto("⋮",laThemeColor(bt,LA_BT_TEXT),middle-LA_RH,middle+LA_RH,ui->U,LA_TEXT_ALIGN_CENTER|LA_TEXT_SHADOW);
+    tnsDrawStringAuto(transLate("🧹 Clear"),laThemeColor(bt,LA_BT_TEXT),L+LA_M,middle-LA_M,U,LA_TEXT_ALIGN_LEFT|LA_TEXT_SHADOW);
+    tnsDrawStringAuto(transLate("Water 💦"),laThemeColor(bt,LA_BT_TEXT),middle+LA_M,R-LA_M,U,LA_TEXT_ALIGN_RIGHT|LA_TEXT_SHADOW);
+    tnsDrawStringAuto("⋮",laThemeColor(bt,LA_BT_TEXT),middle-LA_RH,middle+LA_RH,U,LA_TEXT_ALIGN_CENTER|LA_TEXT_SHADOW);
 
-    tnsDrawStringAuto("◿",laThemeColor(bt,LA_BT_BORDER),ui->R-LA_RH,ui->R,ui->B-LA_RH,LA_TEXT_ALIGN_CENTER|LA_TEXT_SHADOW);
+    tnsDrawStringAuto("◿",laThemeColor(bt,LA_BT_BORDER),R-LA_RH,R,B-LA_RH,LA_TEXT_ALIGN_CENTER|LA_TEXT_SHADOW);
 }
 void our_PigmentPreviewDraw(laUiItem* ui, int h){
     laBoxedTheme *bt = (*ui->Type->Theme);
@@ -1795,7 +1858,7 @@ OurBrush* our_NewBrush(char* name, real SizeOffset, real Hardness, real DabsPerS
     OurBrush* b=memAcquireHyper(sizeof(OurBrush)); strSafeSet(&b->Name,name); lstAppendItem(&Our->Brushes, b);
     b->SizeOffset=SizeOffset; b->Hardness=Hardness; b->DabsPerSize=DabsPerSize; b->Transparency=Transparency; b->Smudge=Smudge;
     b->PressureHardness=PressureHardness; b->PressureSize=PressureSize; b->PressureTransparency=PressureTransparency; b->PressureSmudge=PressureSmudge;
-    b->SmudgeResampleLength = SmudgeResampleLength;
+    b->SmudgeResampleLength = SmudgeResampleLength; b->PressureDepletion=PressureTransparency||PressureSmudge||PressureSize;
     memAssignRef(Our, &Our->CurrentBrush, b);
     b->Rack=memAcquire(sizeof(laRackPage)); b->Rack->RackType=LA_RACK_TYPE_DRIVER;
     b->Binding=-1;
@@ -2391,7 +2454,7 @@ static int ourthread_PigmentConversionSimple16(OurPigmentConversionData* pcd){
     for(int row=pcd->RowStart;row<pcd->RowCount+pcd->RowStart;row++){
         for(int col=0;col<pcd->cols;col++){
             our_GetImagePigmentDataSimple(row*2,col*2,&pd);
-            memcpy(&bkg,canvas,sizeof(real)*16);
+            memcpy(&bkg,canvas,sizeof(real)*32);
             our_PigmentOver(&pd,&bkg,1.0f);
             our_PigmentToXYZDirect(&bkg,xyz);
             pcd->XYZ2RGB(xyz,rgb); TNS_CLAMP(rgb[0],0,1);TNS_CLAMP(rgb[1],0,1);TNS_CLAMP(rgb[2],0,1); tns2LogsRGB(rgb);
@@ -2408,12 +2471,12 @@ static int ourthread_PigmentConversionSimple8(OurPigmentConversionData* pcd){
     for(int row=pcd->RowStart;row<pcd->RowCount+pcd->RowStart;row++){
         for(int col=0;col<pcd->cols;col++){
             our_GetImagePigmentDataSimple(row*2,col*2,&pd);
-            memcpy(&bkg,canvas,sizeof(real)*16);
+            memcpy(&bkg,canvas,sizeof(real)*32);
             our_PigmentOver(&pd,&bkg,1.0f);
             our_PigmentToXYZDirect(&bkg,xyz);
             pcd->XYZ2RGB(xyz,rgb); TNS_CLAMP(rgb[0],0,1);TNS_CLAMP(rgb[1],0,1);TNS_CLAMP(rgb[2],0,1); tns2LogsRGB(rgb);
             uint8_t* pix=&((uint8_t*)pcd->ImageConversionBuffer)[((int64_t)row*pcd->cols+col)*4];
-            pix[0]=rgb[0]*255.0f; pix[1]=rgb[1]*255.0f; pix[2]=rgb[2]*255.0f; pix[3]=255;
+            pix[0]=round(rgb[0]*255.0f); pix[1]=round(rgb[1]*255.0f); pix[2]=round(rgb[2]*255.0f); pix[3]=255;
         }
     }
     return 0;
@@ -2425,7 +2488,7 @@ static int ourthread_PigmentConversionDebayer16(OurPigmentConversionData* pcd){
     for(int row=pcd->RowStart;row<pcd->RowCount+pcd->RowStart;row++){
         for(int col=0;col<pcd->cols;col++){
             our_GetImagePigmentDataDebayer(row,col,&pd);
-            memcpy(&bkg,canvas,sizeof(real)*16);
+            memcpy(&bkg,canvas,sizeof(real)*32);
             our_PigmentOver(&pd,&bkg,1.0f);
             our_PigmentToXYZDirect(&bkg,xyz);
             pcd->XYZ2RGB(xyz,rgb); TNS_CLAMP(rgb[0],0,1);TNS_CLAMP(rgb[1],0,1);TNS_CLAMP(rgb[2],0,1); tns2LogsRGB(rgb);
@@ -2442,12 +2505,12 @@ static int ourthread_PigmentConversionDebayer8(OurPigmentConversionData* pcd){
     for(int row=pcd->RowStart;row<pcd->RowCount+pcd->RowStart;row++){
         for(int col=0;col<pcd->cols;col++){
             our_GetImagePigmentDataDebayer(row,col,&pd);
-            memcpy(&bkg,canvas,sizeof(real)*16);
+            memcpy(&bkg,canvas,sizeof(real)*32);
             our_PigmentOver(&pd,&bkg,1.0f);
             our_PigmentToXYZDirect(&bkg,xyz);
             pcd->XYZ2RGB(xyz,rgb); TNS_CLAMP(rgb[0],0,1);TNS_CLAMP(rgb[1],0,1);TNS_CLAMP(rgb[2],0,1); tns2LogsRGB(rgb);
             uint8_t* pix=&((uint8_t*)pcd->ImageConversionBuffer)[((int64_t)row*pcd->cols+col)*4];
-            pix[0]=rgb[0]*255.0f; pix[1]=rgb[1]*255.0f; pix[2]=rgb[2]*255.0f; pix[3]=255;
+            pix[0]=round(rgb[0]*255.0f); pix[1]=round(rgb[1]*255.0f); pix[2]=round(rgb[2]*255.0f); pix[3]=255;
         }
     }
     return 0;
@@ -2818,7 +2881,7 @@ int our_PaintGetDabs(OurBrush* b, OurLayer* l, real x, real y, real xto, real yt
     if (isnan(x)||isnan(y)||isnan(xto)||isnan(yto)||isinf(x)||isinf(y)||isinf(xto)||isinf(yto)){
         printf("brush input coordinates has nan or inf.\n"); return 0;
     }
-    Our->NextDab=0;
+    Our->NextDab=0; int drained=0;
     if(!b->EvalDabsPerSize) b->EvalDabsPerSize=b->DabsPerSize;
     real smfac=(1-b->Smoothness/1.1); xto=tnsLinearItp(x,xto,smfac); yto=tnsLinearItp(y,yto,smfac);  *r_xto=xto; *r_yto=yto;
     real dd=our_PaintGetDabStepDistance(b->EvalSize, b->EvalDabsPerSize); real len=tnsDistIdv2(x,y,xto,yto); real rem=b->BrushRemainingDist;
@@ -2829,6 +2892,7 @@ int our_PaintGetDabs(OurBrush* b, OurLayer* l, real x, real y, real xto, real yt
     b->EvalSize=bsize; b->EvalHardness=b->Hardness; b->EvalSmudge=b->Smudge; b->EvalSmudgeLength=b->SmudgeResampleLength;
     b->EvalTransparency=b->Transparency; b->EvalDabsPerSize=b->DabsPerSize; b->EvalSlender=b->Slender; b->EvalAngle=b->Angle;
     b->EvalSpeed=tnsDistIdv2(x,y,xto,yto)/bsize; b->EvalForce=b->Force; b->EvalGunkyness=b->Gunkyness; b->EvalAccumulation=b->Accumulation;
+    b->EvalDepletionSpeed=b->DepletionSpeed; real drain_delta;
     if(Our->ResetBrush){ b->LastX=x; b->LastY=y; b->LastAngle=atan2(yto-y,xto-x); b->EvalStrokeLength=0; Our->ResetBrush=0; }
     real this_angle=atan2(yto-y,xto-x);
     if(b->LastAngle-this_angle>TNS_PI){ this_angle+=(TNS_PI*2); }
@@ -2853,6 +2917,7 @@ int our_PaintGetDabs(OurBrush* b, OurLayer* l, real x, real y, real xto, real yt
             od->Size = b->EvalSize*pfac(b->PressureSize);       od->Hardness = b->EvalHardness*pfac(b->PressureHardness);
             od->Smudge = b->EvalSmudge*pfac(b->PressureSmudge); od->Color[3]=pow(b->EvalTransparency*pfac(b->PressureTransparency),2.718);
             tnsVectorSet3v(od->Color,b->EvalColor);             od->Force=b->EvalForce*pfac(b->PressureForce);
+            if(b->Iteration==0){ drain_delta=b->EvalDepletionSpeed/b->EvalDabsPerSize/100.0f*pfac(b->PressureDepletion); }
     #undef pfac;
             od->Gunkyness = b->EvalGunkyness; od->Slender = b->EvalSlender; od->Accumulation=b->EvalAccumulation;
             od->Angle=b->EvalAngle; if(b->TwistAngle){ od->Angle=tnsInterpolate(last_twist,Twist,r); }
@@ -2860,6 +2925,8 @@ int our_PaintGetDabs(OurBrush* b, OurLayer* l, real x, real y, real xto, real yt
             ymin=TNS_MIN2(ymin, od->Y-od->Size); ymax=TNS_MAX2(ymax, od->Y+od->Size);
             if(od->Size>1e-1 && (!b->EvalDiscard)) Our->NextDab++;
         }
+        b->PigmentLoading-=drain_delta; if(b->PigmentLoading<0) b->PigmentLoading=0; if(drain_delta){ drained=1; }
+        if(!b->UseNodes) od->Color[3]*=b->PigmentLoading;
         step=our_PaintGetDabStepDistance(od->Size, b->EvalDabsPerSize);
         b->EvalStrokeLength+=step/bsize; b->EvalStrokeLengthAccum+=step/bsize; if(b->EvalStrokeLengthAccum>1e6){b->EvalStrokeLengthAccum-=1e6;}
         od->ResampleSmudge=0;
@@ -2872,6 +2939,7 @@ int our_PaintGetDabs(OurBrush* b, OurLayer* l, real x, real y, real xto, real yt
     if(this_angle>TNS_PI*2){ this_angle-=(TNS_PI*2); }
     b->LastAngle=this_angle;
     b->BrushRemainingDist=alllen-uselen;
+    if(drained){ laNotifyInstanceUsers(b); }
     if(Our->NextDab) {
         our_LayerEnsureTiles(l,xmin,xmax,ymin,ymax,0,tl,tr,tu,tb);
         int pxw=Our->PigmentMode?1:0;
@@ -4325,7 +4393,7 @@ void ourset_CurrentBrush(void* unused, OurBrush* b){
         if(b->DefaultAsEraser){ Our->Erasing=1; Our->EraserID=b->Binding; if(Our->SaveEraserSize)Our->BrushSize=Our->SaveEraserSize; }
         else{ Our->Erasing=0; Our->PenID=b->Binding; if(Our->SaveBrushSize)Our->BrushSize=Our->SaveBrushSize; }
     }
-    Our->ShowBrushName = 1; Our->ShowBrushNumber=1;
+    Our->ShowBrushName = 1; Our->ShowBrushNumber=1; b->PigmentLoading=1;
     laNotifyUsers("our.tools.current_brush"); laNotifyUsers("our.erasing"); laGraphRequestRebuild();
 }
 void ourset_CurrentPigment(void* unused, OurPigment* p){
@@ -4863,6 +4931,7 @@ void ourRegisterEverything(){
     laAddEnumItemAs(p,"SHOWN","Shown","Show light and surface chooser on header",1,0);
     laAddFloatProperty(pc,"smoothness","Smoothness","Smoothness of global brush input",0,0, 0,1,0,0.05,0,0,offsetof(OurPaint,Smoothness),0,0,0,0,0,0,0,0,0,0,0);
     laAddFloatProperty(pc,"hardness","Strength","Pressure strength of global brush input",0,0, 0,1,-1,0.05,0,0,offsetof(OurPaint,Hardness),0,0,0,0,0,0,0,0,0,0,0);
+    laAddFloatProperty(pc,"mixing_speed","Mixing Speed","Speed to mix pigments on the ui",0,0, 0,5,0,0.05,0,0,offsetof(OurPaint,MixingSpeed),0,0,0,0,0,0,0,0,0,0,0);
     p=laAddEnumProperty(pc,"show_stripes","Ref Stripes","Whether to show visual reference stripes",LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(OurPaint,ShowStripes),0,ourset_ShowStripes,0,0,0,0,0,0,0,0);
     laAddEnumItemAs(p,"FALSE","No","Don't show visual reference stripes",0,0);
     laAddEnumItemAs(p,"TRUE","Yes","Show visual reference stripes at the top and bottom of the canvas",1,0);
@@ -4974,6 +5043,8 @@ void ourRegisterEverything(){
     laAddFloatProperty(pc,"force","Force","How hard the brush is pushed against canvas texture",0,0,0,1,0,0.05,0,0,offsetof(OurBrush,Force),0,0,0,0,0,0,0,0,0,0,0);
     laAddFloatProperty(pc,"gunkyness","Gunkyness","How will the brush stick to the canvas texture",0,0, 0,1,-1,0.05,0,0,offsetof(OurBrush,Gunkyness),0,0,0,0,0,0,0,0,0,0,0);
     laAddFloatProperty(pc,"accumulation","Accumulation","How fast pigments accumulate",0,0,0,5,0,0.05,3,0,offsetof(OurBrush,Accumulation),0,0,0,0,0,0,0,0,0,0,0);
+    laAddFloatProperty(pc,"depletion_speed","Depletion Speed","How fast pigments left the brush",0,0,0,1,0,0.05,3,0,offsetof(OurBrush,DepletionSpeed),0,0,0,0,0,0,0,0,0,0,0);
+    laAddFloatProperty(pc,"pigment_loading","Pigment Loading","How much paint is on the brush",OUR_WIDGET_PIGMENT_LOADER,0,0,1,0,0.05,1,0,offsetof(OurBrush,PigmentLoading),0,0,0,0,0,0,0,0,0,0,LA_UDF_IGNORE);
     laAddFloatProperty(pc,"c1","C1","Custom brush input 1",0,0, 0,0,0,0.05,0,0,offsetof(OurBrush,Custom1),0,0,0,0,0,0,0,0,0,0,0);
     laAddFloatProperty(pc,"c2","C2","Custom brush input 2",0,0, 0,0,0,0.05,0,0,offsetof(OurBrush,Custom2),0,0,0,0,0,0,0,0,0,0,0);
     laAddStringProperty(pc,"c1_name","C1 Name","Custom input 1 name",0,0,0,0,1,offsetof(OurBrush,Custom1Name),0,0,0,0,0);
@@ -4988,6 +5059,8 @@ void ourRegisterEverything(){
     OUR_ADD_PRESSURE_SWITCH(p);
     p=laAddEnumProperty(pc,"pressure_force","Pressure Force","Use pen pressure to control dab force",LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(OurBrush,PressureForce),0,0,0,0,0,0,0,0,0,0);
     OUR_ADD_PRESSURE_SWITCH(p);
+    p=laAddEnumProperty(pc,"pressure_depletion","Pressure Depletion","Use pen pressure to control depletion speed",LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(OurBrush,PressureDepletion),0,0,0,0,0,0,0,0,0,0);
+    OUR_ADD_PRESSURE_SWITCH(p);
     p=laAddEnumProperty(pc,"twist_angle","Twist Angle","Use pen twist to control dab angle",LA_WIDGET_ENUM_HIGHLIGHT,0,0,0,0,offsetof(OurBrush,TwistAngle),0,0,0,0,0,0,0,0,0,0);
     laAddEnumItemAs(p,"NONE","None","Not using twist",0,0);
     laAddEnumItemAs(p,"ENABLED","Enabled","Using twist",1,0);
@@ -5124,12 +5197,15 @@ void ourRegisterEverything(){
     laAddEnumItemAs(p,"SKETCH","Sketch","Layer is a sketch layer",1,U'🖉');
 
     laCreateOperatorType("OUR_UIOP_pigment_mixer","Pigment Mixer","Pigment display widget operator",0,0,0,OPINV_UiItem,ourmod_PigmentMixer,0,LA_EXTRA_TO_PANEL);
+    laCreateOperatorType("OUR_UIOP_pigment_loader","Pigment Loader","For loading pigment onto brush when they run out",0,0,0,OPINV_UiItem,ourmod_PigmentLoader,0,LA_EXTRA_TO_PANEL);
     laCreateOperatorType("OUR_UIOP_color_pad","Color Pad","UI operator for color pads that mixes color",0,0,0,OPINV_UiItem,ourmod_ColorPad,0,LA_EXTRA_TO_PANEL);
 
     OUR_WIDGET_PIGMENT_MIXER->Type=
     _OUR_UI_PIGMENT_MIXER = la_RegisterUiType("OUR_UI_pigment_mixer", 0, "OUR_UIOP_pigment_mixer", &_LA_THEME_VALUATOR, our_PigmentMixerDraw, 0, la_GeneralUiInit, la_GeneralUiDestroy);
     OUR_WIDGET_PIGMENT_PREVIEW->Type=
     _OUR_UI_PIGMENT_PREVIEW = la_RegisterUiType("OUR_UI_pigment_preview", 0, 0, &_LA_THEME_VALUATOR, our_PigmentPreviewDraw, 0, 0, 0);
+    OUR_WIDGET_PIGMENT_LOADER->Type=
+    _OUR_UI_PIGMENT_LOADER = la_RegisterUiType("OUR_UI_pigment_loader", 0, "OUR_UIOP_pigment_loader", &_LA_THEME_VALUATOR, our_PigmentLoaderDraw, 0, 0, 0);
     OUR_WIDGET_COLOR_PAD->Type=
     _OUR_UI_COLOR_PAD = la_RegisterUiType("OUR_UI_color_pad", 0, "OUR_UIOP_color_pad", &_LA_THEME_VALUATOR, our_ColorPadDraw, 0, 0, 0);
 
@@ -5497,6 +5573,7 @@ int ourInit(){
     Our->SegmentedWrite = 1;
     Our->CanvasVersion=ourget_AssetVersion(0);
     Our->AlphaMode=1;
+    Our->MixingSpeed=0.5;
 
     Our->CanvasLight=memAcquireHyper(sizeof(OurLight));
     Our->CanvasSurface=memAcquireHyper(sizeof(OurCanvasSurface));

+ 7 - 2
ourpaint.h

@@ -124,7 +124,7 @@ STRUCTURE(OurCanvasDraw){
 
 #define OUR_SPECTRAL_SLICES 14
 
-#define OUR_MIXING_SPEED 0.05f
+#define OUR_MIXING_SPEED (Our->MixingSpeed/10.0f)
 
 #define OUR_TILE_W 1024
 #define OUR_TILES_PER_ROW 100
@@ -194,6 +194,7 @@ STRUCTURE(OurBrushSettingsNode){
     laNodeOutSocket* Angle;        real rAngle;
     laNodeOutSocket* Gunkyness;    real rGunkyness;
     laNodeOutSocket* Accumulation; real rAccumulation;
+    laNodeOutSocket* DepletionSpeed;real rDepletionSpeed;
     laNodeOutSocket* Force;        real rForce;
     laNodeOutSocket* Color;
     laNodeOutSocket* Iteration;    int  rIteration;
@@ -214,6 +215,7 @@ STRUCTURE(OurBrushOutputsNode){
     laNodeInSocket* Color;
     laNodeInSocket* Gunkyness;
     laNodeInSocket* Accumulation;
+    laNodeInSocket* DepletionSpeed;
     laNodeInSocket* Force;
     laNodeInSocket* Repeats;
     laNodeInSocket* Discard;
@@ -247,8 +249,9 @@ STRUCTURE(OurBrush){
     real MaxStrokeLength;
     real Custom1,Custom2; laSafeString *Custom1Name,*Custom2Name;
     real Accumulation;
+    real DepletionSpeed;
     int Iteration;
-    int PressureSize,PressureHardness,PressureTransparency,PressureSmudge,PressureForce,TwistAngle; // the simple way
+    int PressureSize,PressureHardness,PressureTransparency,PressureSmudge,PressureForce,TwistAngle,PressureDepletion; // the simple way
 
     int Binding,DefaultAsEraser;
     int ShowInPages;
@@ -274,6 +277,7 @@ STRUCTURE(OurBrush){
     real EvalAngle;
     real EvalForce, EvalGunkyness;
     real EvalAccumulation;
+    real EvalDepletionSpeed, PigmentLoading;
 
     real EvalSpeed;
     real EvalStrokeLength;
@@ -510,6 +514,7 @@ STRUCTURE(OurPaint){
     laSafeString* Notes;
 
     real Smoothness,Hardness;
+    real MixingSpeed;
     real LastX, LastY;
 
     real CurrentScale;

+ 2 - 1
ourtranslations_es-ES.c

@@ -28,6 +28,8 @@ extern tnsMain* T;
 extern OurPaint *Our;
 
 static const char *entries[]={
+"Depletion Speed","耗尽速度",
+"Mixing Speed","混合速度",
 "Pigment Conversion Method:","以何种方式将颜料转换为像素:",
 "Pixel Binning","像素合并",
 "See list of Sponsors", "查看赞助者列表",
@@ -197,7 +199,6 @@ static const char *entries[]={
 "Canvas Scale","Escala de Lienzo",
 "Others","Otros",
 "Bit Depth","Profundidad de Bit",
-"Our Paint v0.1c","Our Paint v0.1c",
 "New Layer","Nueva Capa",
 "Color Space","Espacio de Color",
 "Our Paint","Our Paint",

+ 3 - 1
ourtranslations_zh-hans.c

@@ -23,6 +23,8 @@ extern tnsMain* T;
 extern OurPaint *Our;
 
 static const char *entries[]={
+"Depletion Speed","耗尽速度",
+"Mixing Speed","混合速度",
 "Pigment Conversion Method:","以何种方式将颜料转换为像素:",
 "Pixel Binning","像素合并",
 "See list of Sponsors", "查看赞助者列表",
@@ -199,7 +201,7 @@ static const char *entries[]={
 "Canvas Scale","画布缩放",
 "Others","其他",
 "Bit Depth","位深度",
-"Our Paint v0.1c","好得涂 v0.1c",
+"Our Paint v0.5","好得涂 v0.5",
 "New Layer","新图层",
 "Color Space","色彩空间",
 "Our Paint","好得涂",