*/}}
Browse Source

Save layers

Yiming Wu 1 year ago
parent
commit
aa14f4c2d2
2 changed files with 122 additions and 28 deletions
  1. 110 26
      ouroperations.c
  2. 12 2
      ourpaint.h

+ 110 - 26
ouroperations.c

@@ -188,7 +188,7 @@ void our_CanvasDrawTextures(){
         for(int row=0;row<OUR_TEX_TILES_PER_ROW;row++){
             if(!l->TexTiles[row]) continue;
             for(int col=0;col<OUR_TEX_TILES_PER_ROW;col++){
-                if(!l->TexTiles[row][col]) continue;
+                if(!l->TexTiles[row][col] || !l->TexTiles[row][col]->Texture) continue;
                 int sx=((real)col-OUR_TEX_TILE_CTR-0.5)*OUR_TEX_TILE_W_USE-OUR_TEX_TILE_SEAM,sy=((real)row-OUR_TEX_TILE_CTR-0.5)*OUR_TEX_TILE_W_USE-OUR_TEX_TILE_SEAM;            
                 real pad=(real)OUR_TEX_TILE_SEAM/OUR_TEX_TILE_W; int seam=OUR_TEX_TILE_SEAM;
                 tnsDraw2DTextureArg(l->TexTiles[row][col]->Texture,sx+seam,sy+OUR_TEX_TILE_W-seam,OUR_TEX_TILE_W-seam*2,-OUR_TEX_TILE_W+seam*2,0,pad,pad,pad,pad);
@@ -205,7 +205,7 @@ void our_CanvasDrawTiles(){
     for(int row=0;row<OUR_TEX_TILES_PER_ROW;row++){
         if(!l->TexTiles[row]) continue;
         for(int col=0;col<OUR_TEX_TILES_PER_ROW;col++){
-            if(!l->TexTiles[row][col]) continue;
+            if(!l->TexTiles[row][col] || !l->TexTiles[row][col]->Texture) continue;
             int sx=((real)col-OUR_TEX_TILE_CTR-0.5)*OUR_TEX_TILE_W_USE-OUR_TEX_TILE_SEAM,sy=((real)row-OUR_TEX_TILE_CTR-0.5)*OUR_TEX_TILE_W_USE-OUR_TEX_TILE_SEAM;            
             //tnsVertex2d(sx, sy); tnsVertex2d(sx+OUR_TEX_TILE_W,sy);
             //tnsVertex2d(sx+OUR_TEX_TILE_W, sy+OUR_TEX_TILE_W); tnsVertex2d(sx,sy+OUR_TEX_TILE_W);
@@ -304,15 +304,31 @@ void our_CanvasDrawOverlay(laUiItem* ui,int h){
 }
 
 OurLayer* our_NewLayer(char* name){
-    OurLayer* l=memAcquire(sizeof(OurLayer)); strSafeSet(&l->Name,name); lstPushItem(&Our->Layers, l);
+    OurLayer* l=memAcquireHyper(sizeof(OurLayer)); strSafeSet(&l->Name,name); lstPushItem(&Our->Layers, l);
     memAssignRef(Our, &Our->CurrentLayer, l);
     return l;
 }
 void our_RemoveLayer(OurLayer* l){
     strSafeDestroy(&l->Name); lstRemoveItem(&Our->Layers, l);
     if(Our->CurrentLayer==l){ OurLayer* nl=l->Item.pPrev?l->Item.pPrev:l->Item.pNext; memAssignRef(Our, &Our->CurrentLayer, nl); }
+    for(int row=0;row<OUR_TEX_TILES_PER_ROW;row++){ if(!l->TexTiles[row]) continue;
+        for(int col=0;col<OUR_TEX_TILES_PER_ROW;col++){ if(!l->TexTiles[row][col]) continue;
+            if(l->TexTiles[row][col]->Texture) tnsDeleteTexture(l->TexTiles[row][col]->Texture); l->TexTiles[row][col]->Texture=0;
+            if(l->TexTiles[row][col]->Data) free(l->TexTiles[row][col]->Data); l->TexTiles[row][col]->Data=0;
+        }
+    }
     memLeave(l);
 }
+void ourbeforefree_Layer(OurLayer* l){
+    for(int row=0;row<OUR_TEX_TILES_PER_ROW;row++){ if(!l->TexTiles[row]) continue;
+        for(int col=0;col<OUR_TEX_TILES_PER_ROW;col++){ if(!l->TexTiles[row][col]) continue;
+            if(l->TexTiles[row][col]->Texture) tnsDeleteTexture(l->TexTiles[row][col]->Texture); l->TexTiles[row][col]->Texture=0;
+            if(l->TexTiles[row][col]->Data) free(l->TexTiles[row][col]->Data); l->TexTiles[row][col]->Data=0;
+            memFree(l->TexTiles[row][col]);
+        }
+        memFree(l->TexTiles[row]); l->TexTiles[row]=0;
+    }
+}
 OurBrush* our_NewBrush(char* name, real Size, real Hardness, real DabsPerSize, real Transparency, real Smudge, real SmudgeResampleLength,
     int PressureSize, int PressureHardness, int PressureTransparency, int PressureSmudge){
     OurBrush* b=memAcquireHyper(sizeof(OurBrush)); strSafeSet(&b->Name,name); lstAppendItem(&Our->Brushes, b);
@@ -328,6 +344,12 @@ void our_RemoveBrush(OurBrush* b){
     memLeave(b);
 }
 
+int our_BufferAnythingVisible(uint16_t* buf, int elemcount){
+    for(int i=0;i<elemcount;i++){
+        uint16_t* rgba=&buf[i*4]; if(rgba[3]) return 1;
+    }
+    return 0;
+}
 void our_LayerEnsureTiles(OurLayer* ol, real xmin,real xmax, real ymin,real ymax, int Aligned, int *tl, int *tr, int* tu, int* tb){
     int l,r,u,b;
     if(Aligned){
@@ -351,6 +373,7 @@ void our_LayerEnsureTiles(OurLayer* ol, real xmin,real xmax, real ymin,real ymax
             if(ol->TexTiles[row][col]) continue;
             ol->TexTiles[row][col]=memAcquireSimple(sizeof(OurTexTile));
             ol->TexTiles[row][col]->Texture=tnsCreate2DTexture(GL_RGBA16,OUR_TEX_TILE_W,OUR_TEX_TILE_W,0);
+            ol->TexTiles[row][col]->row=row; ol->TexTiles[row][col]->col=col;
             uint16_t initColor[]={0,0,0,0};
             glClearTexImage(ol->TexTiles[row][col]->Texture->GLTexHandle, 0, GL_RGBA, GL_UNSIGNED_SHORT, 0);
         }
@@ -367,7 +390,7 @@ void our_TileTextureToImage(OurTexTile* ot, int SX, int SY){
     for(int row=0;row<OUR_TEX_TILE_W_USE;row++){
         memcpy(&Our->ImageBuffer[((SY+row)*Our->ImageW+SX)*4],&ot->Data[(row*OUR_TEX_TILE_W_USE)*4],sizeof(uint16_t)*4*OUR_TEX_TILE_W_USE);
     }
-    free(ot->Data);
+    free(ot->Data); ot->Data=0;
 }
 void our_TileImageToTexture(OurTexTile* ot, int SX, int SY){
     int pl=(SX!=0)?OUR_TEX_TILE_SEAM:0, pr=((SX+OUR_TEX_TILE_W_USE)!=Our->ImageW)?OUR_TEX_TILE_SEAM:0;
@@ -377,11 +400,14 @@ void our_TileImageToTexture(OurTexTile* ot, int SX, int SY){
     for(int row=0;row<height;row++){
         memcpy(&ot->Data[((row)*width)*4],&Our->ImageBuffer[((SY+row-pu)*Our->ImageW+SX-pl)*4],sizeof(uint16_t)*4*width);
     }
-    tnsBindTexture(ot->Texture);
-    glTexSubImage2D(GL_TEXTURE_2D, 0, OUR_TEX_TILE_SEAM-pl, OUR_TEX_TILE_SEAM-pu, width, height, GL_RGBA, GL_UNSIGNED_SHORT, ot->Data);
-    free(ot->Data);
+    if(!our_BufferAnythingVisible(ot->Data, bufsize/sizeof(uint16_t)/4)){ tnsDeleteTexture(ot->Texture); ot->Texture=0; }
+    else{
+        tnsBindTexture(ot->Texture);
+        glTexSubImage2D(GL_TEXTURE_2D, 0, OUR_TEX_TILE_SEAM-pl, OUR_TEX_TILE_SEAM-pu, width, height, GL_RGBA, GL_UNSIGNED_SHORT, ot->Data);
+    }
+    free(ot->Data); ot->Data=0;
 }
-int our_LayerEnsureImageBuffer(OurLayer* ol){
+int our_LayerEnsureImageBuffer(OurLayer* ol, int OnlyCalculate){
     int l=1000,r=-1000,u=-1000,b=1000; int any=0;
     for(int row=0;row<OUR_TEX_TILES_PER_ROW;row++){ if(!ol->TexTiles[row]) continue;
         if(row<b) b=row; if(row>u) u=row;
@@ -392,8 +418,10 @@ int our_LayerEnsureImageBuffer(OurLayer* ol){
     if(!any) return 0;
     Our->ImageW = OUR_TEX_TILE_W_USE*(r-l+1); Our->ImageH = OUR_TEX_TILE_W_USE*(u-b+1);
     Our->ImageX =((real)l-OUR_TEX_TILE_CTR-0.5)*OUR_TEX_TILE_W_USE; Our->ImageY=((real)b-OUR_TEX_TILE_CTR-0.5)*OUR_TEX_TILE_W_USE;
-    if(Our->ImageBuffer) free(Our->ImageBuffer);
-    Our->ImageBuffer = calloc(Our->ImageW*4,Our->ImageH*sizeof(uint16_t));
+    if(!OnlyCalculate){
+        if(Our->ImageBuffer) free(Our->ImageBuffer);
+        Our->ImageBuffer = calloc(Our->ImageW*4,Our->ImageH*sizeof(uint16_t));
+    }
     return 1;
 }
 void our_LayerToImageBuffer(OurLayer* ol){
@@ -412,16 +440,30 @@ void our_LayerToTexture(OurLayer* ol){
         }
     }
 }
-int our_LayerExportPNG(OurLayer* l, FILE* fp){
-    if(!l||!fp) return 0;
+static void _our_png_write(png_structp png_ptr, png_bytep data, png_size_t length){
+    OurLayerWrite* LayerWrite=png_get_io_ptr(png_ptr);
+    arrEnsureLength(&LayerWrite->data,LayerWrite->NextData+length,&LayerWrite->MaxData,sizeof(unsigned char));
+    memcpy(&LayerWrite->data[LayerWrite->NextData], data, length);
+    LayerWrite->NextData+=length;
+}
+int our_LayerExportPNG(OurLayer* l, FILE* fp, int WriteToBuffer, void** buf, int* sizeof_buf){
+    if(!l||(!fp&&!WriteToBuffer)) return 0;
 
-    if(!our_LayerEnsureImageBuffer(l)) return 0;
+    if(!our_LayerEnsureImageBuffer(l, 0)) return 0;
 
     our_LayerToImageBuffer(l);
 
     png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);
     png_infop info_ptr = png_create_info_struct(png_ptr);
-    png_init_io(png_ptr, fp);
+
+    OurLayerWrite LayerWrite={0};
+
+    if(WriteToBuffer){
+        arrEnsureLength(&LayerWrite.data,0,&LayerWrite.MaxData,sizeof(unsigned char));
+        png_set_write_fn(png_ptr,&LayerWrite,_our_png_write,0);
+    }else{
+        png_init_io(png_ptr, fp);
+    }
     
     png_set_IHDR(png_ptr, info_ptr,Our->ImageW,Our->ImageH,16,PNG_COLOR_TYPE_RGBA,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_BASE,PNG_FILTER_TYPE_BASE);
     // Should not set gamma, we should set either srgb chunk or iccp. Gimp bug: https://gitlab.gnome.org/GNOME/gimp/-/issues/5363
@@ -444,21 +486,30 @@ int our_LayerExportPNG(OurLayer* l, FILE* fp){
     png_destroy_write_struct(&png_ptr, &info_ptr);
     free(Our->ImageBuffer); Our->ImageBuffer=0;
 
+    if(WriteToBuffer){ *buf=LayerWrite.data; *sizeof_buf=LayerWrite.NextData; }
+
     return 1;
 }
-void our_EnsureImageBufferOnRead(OurLayer*l, int W, int H, int Align, int StartX, int StartY){
+void our_EnsureImageBufferOnRead(OurLayer*l, int W, int H, int UseOffsets, int StartX, int StartY){
     int tw=W/OUR_TEX_TILE_W_USE, th=H/OUR_TEX_TILE_W_USE;
     int w=tw*OUR_TEX_TILE_W_USE, h=th*OUR_TEX_TILE_W_USE;
     if(w<W){ tw+=1; w+=OUR_TEX_TILE_W_USE; } if(h<H){ th+=1; h+=OUR_TEX_TILE_W_USE; }
 
-    int ix=-tw/2*OUR_TEX_TILE_W_USE-OUR_TEX_TILE_W_USE/2, iy=th/2*OUR_TEX_TILE_W_USE+OUR_TEX_TILE_W_USE/2; int tl,tr,tu,tb;
+    int ix=UseOffsets?StartX:(-tw/2*OUR_TEX_TILE_W_USE-OUR_TEX_TILE_W_USE/2);
+    int iy=UseOffsets?StartY:(th/2*OUR_TEX_TILE_W_USE+OUR_TEX_TILE_W_USE/2);
+    int tl,tr,tu,tb;
     our_LayerEnsureTiles(l,ix,ix+W,iy-H,iy,1,&tl,&tr,&tu,&tb);
-    our_LayerEnsureImageBuffer(l);
+    our_LayerEnsureImageBuffer(l, 0);
     Our->LoadX = ix-Our->ImageX; Our->LoadY = Our->ImageY+Our->ImageH-iy;
 }
-int our_LayerImportPNG(OurLayer* l, FILE* fp, int UseProfile){
+static void _our_png_read(png_struct *ps, png_byte *data, png_size_t length){
+    OurLayerRead *LayerRead = (OurLayerRead*)png_get_io_ptr(ps);
+    memcpy(data,&LayerRead->data[LayerRead->NextData],length);
+    LayerRead->NextData+=length;
+}
+int our_LayerImportPNG(OurLayer* l, FILE* fp, void* buf, int UseProfile, int UseOffsets, int StartX, int StartY){
     int result=0;
-    if(!fp || !l) return 0;
+    if((!fp&&!buf) || !l) return 0;
 
     int srgb_intent = 0;
     png_charp icc_profile_name = NULL;
@@ -474,10 +525,16 @@ int our_LayerImportPNG(OurLayer* l, FILE* fp, int UseProfile){
     png_bytep icc_profile = NULL;
 #endif
 
+    OurLayerRead LayerRead={0};
+
     png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,0,0,0); if (!png_ptr) { return 0; }
     png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { return 0; }
     if (setjmp(png_jmpbuf(png_ptr))) { goto cleanup_png_read; }
-    png_init_io(png_ptr, fp);
+    if(buf){
+        LayerRead.data=buf; png_set_read_fn(png_ptr, &LayerRead, _our_png_read);
+    }else{
+        png_init_io(png_ptr, fp);
+    }
     png_read_info(png_ptr, info_ptr);
     png_set_swap(png_ptr);
 
@@ -548,7 +605,7 @@ int our_LayerImportPNG(OurLayer* l, FILE* fp, int UseProfile){
     int W = png_get_image_width(png_ptr, info_ptr);
     int H = png_get_image_height(png_ptr, info_ptr);
 
-    our_EnsureImageBufferOnRead(l,W,H,1,0,0);
+    our_EnsureImageBufferOnRead(l,W,H,UseOffsets,StartX,StartY);
 
     for(int i=0;i<H;i++){
         png_read_row(png_ptr, &Our->ImageBuffer[((H-i-1+Our->LoadY)*Our->ImageW+Our->LoadX)*4], NULL);
@@ -740,7 +797,7 @@ int ourmod_ExportLayer(laOperator* a, laEvent* e){
         if (a->ConfirmData->StrData){
             FILE* fp=fopen(a->ConfirmData->StrData,"wb");
             if(!fp) return LA_FINISHED;
-            our_LayerExportPNG(Our->CurrentLayer, fp);
+            our_LayerExportPNG(Our->CurrentLayer, fp, 0, 0, 0);
             fclose(fp);
         }
         return LA_FINISHED;
@@ -759,7 +816,7 @@ int ourmod_ImportLayer(laOperator* a, laEvent* e){
             FILE* fp=fopen(a->ConfirmData->StrData,"rb");
             if(!fp) return LA_FINISHED;
             if(!ol) ol=our_NewLayer("Imported");
-            our_LayerImportPNG(ol, fp, 0);
+            our_LayerImportPNG(ol, fp, 0, 0, 0, 0, 0);
             fclose(fp);
         }
         return LA_FINISHED;
@@ -862,6 +919,21 @@ void* ourget_FirstBrush(void* unused, void* unused1){
 void* ourget_our(void* unused, void* unused1){
     return Our;
 }
+void ourget_LayerTileStart(OurLayer* l, int* xy){
+    our_LayerEnsureImageBuffer(l, 1); xy[0]=Our->ImageX; xy[1]=Our->ImageY+Our->ImageH;
+}
+void ourset_LayerTileStart(OurLayer* l, int* xy){
+    Our->TempLoadX = xy[0]; Our->TempLoadY = xy[1];
+}
+void* ourget_LayerImage(OurLayer* l, int* r_size, int* r_is_copy){
+    void* buf=0;
+    if(our_LayerExportPNG(l,0,1,&buf,r_size)){ *r_is_copy=1; return buf; }
+    *r_is_copy=0; return buf;
+}
+void ourset_LayerImage(OurLayer* l, void* data, int size){
+    if(!data) return;
+    our_LayerImportPNG(l, 0, data, 0, 1, Our->TempLoadX, Our->TempLoadY);
+}
 void ourset_LayerMove(OurLayer* l, int move){
     if(move<0 && l->Item.pPrev){ lstMoveUp(&Our->Layers, l); laNotifyUsers("our.canvas.layers"); }
     elif(move>0 && l->Item.pNext){ lstMoveDown(&Our->Layers, l); laNotifyUsers("our.canvas.layers"); }
@@ -888,6 +960,12 @@ void ourset_CanvasSize(void* unused, int* wh){
 void ourset_CanvasPosition(void* unused, int* xy){
     Our->X=xy[0]; Our->Y=xy[1]; laNotifyUsers("our.canvas");
 }
+void ourset_LayoutPosition(OurLayer* l, int* xy){
+    l->OffsetX=xy[0]; l->OffsetY=xy[1]; laNotifyUsers("our.canvas");
+}
+void ourreset_Canvas(OurPaint* op){
+    while(op->Layers.pFirst){ our_RemoveLayer(op->Layers.pFirst); }
+}
 
 #define OUR_ADD_PRESSURE_SWITCH(p)\
     laAddEnumItemAs(p,"NONE","None","Not using pressure",0,0);\
@@ -927,7 +1005,7 @@ void ourRegisterEverything(){
     laRegisterUiTemplate("panel_color", "Color", ourui_ColorPanel, 0, 0,0);
     
     pc=laDefineRoot();
-    laAddSubGroup(pc,"our","Our","OurPaint main","our_paint",0,0,0,-1,ourget_our,0,0,0,0,0,0,0);
+    laAddSubGroup(pc,"our","Our","OurPaint main","our_paint",0,0,0,-1,ourget_our,0,0,0,0,0,0,LA_UDF_SINGLE);
 
     pc=laAddPropertyContainer("our_paint","Our Paint","OurPaint main",0,0,sizeof(OurPaint),0,0,1);
     laAddSubGroup(pc,"canvas","Canvas","OurPaint canvas","our_canvas",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
@@ -964,15 +1042,19 @@ void ourRegisterEverything(){
     laAddOperatorProperty(pc,"remove","Remove","Remove brush","OUR_remove_brush",L'🗴',0);
 
     pc=laAddPropertyContainer("our_canvas","Our Canvas","OurPaint canvas",0,0,sizeof(OurPaint),0,0,1);
+    laPropContainerExtraFunctions(pc,0,ourreset_Canvas,0,0,0);
     laAddSubGroup(pc,"layers","Layers","Layers","our_layer",0,0,ourui_Layer,offsetof(OurPaint,CurrentLayer),0,0,0,0,0,0,offsetof(OurPaint,Layers),0);
     laAddSubGroup(pc,"current_layer","Current Layer","Current layer","our_layer",0,0,0,offsetof(OurPaint,CurrentLayer),ourget_FirstLayer,0,laget_ListNext,0,0,0,0,LA_UDF_REFER);
     laAddIntProperty(pc,"size","Size","Size of the cropping area",0,"X,Y","px",0,0,0,2400,0,offsetof(OurPaint,W),0,0,2,0,0,0,0,ourset_CanvasSize,0,0,0);
     laAddIntProperty(pc,"position","Position","Position of the cropping area",0,"X,Y","px",0,0,0,2400,0,offsetof(OurPaint,X),0,0,2,0,0,0,0,ourset_CanvasPosition,0,0,0);
 
-    pc=laAddPropertyContainer("our_layer","Our Layer","OurPaint layer",0,0,sizeof(OurLayer),0,0,1);
+    pc=laAddPropertyContainer("our_layer","Our Layer","OurPaint layer",0,0,sizeof(OurLayer),0,0,2);
+    laPropContainerExtraFunctions(pc,ourbeforefree_Layer,ourbeforefree_Layer,0,0,0);
     laAddStringProperty(pc,"name","Name","Name of the layer",0,0,0,0,1,offsetof(OurLayer,Name),0,0,0,0,LA_AS_IDENTIFIER);
     laAddIntProperty(pc,"__move","Move Slider","Move Slider",LA_WIDGET_HEIGHT_ADJUSTER,0,0,0,0,0,0,0,0,0,ourset_LayerMove,0,0,0,0,0,0,0,0,0);
-    //laAddSubGroup(pc,"Rows","Rows","Rows of tiles","our_rows",0,0,0,0,0,0,0,0,0,0,offsetof(OurLayer,Rows),0);
+    laAddIntProperty(pc,"offset","Offset","Offset of the layer",0,"X,Y","px",0,0,0,0,0,offsetof(OurLayer,OffsetX),0,0,2,0,0,0,0,ourset_LayoutPosition,0,0,0);
+    laAddIntProperty(pc,"tile_start","Tile Start","Tile starting position for loading",0,0,0,0,0,0,0,0,0,0,0,2,0,0,ourget_LayerTileStart,0,ourset_LayerTileStart,0,0,LA_UDF_ONLY);
+    laAddRawProperty(pc,"image","Image","The image data of this tile",0,0,ourget_LayerImage,ourset_LayerImage,LA_UDF_ONLY);
     laAddOperatorProperty(pc,"move","Move","Move Layer","OUR_move_layer",0,0);
     laAddOperatorProperty(pc,"remove","Remove","Remove layer","OUR_remove_layer",L'🗴',0);
 
@@ -987,6 +1069,8 @@ void ourRegisterEverything(){
     laAssignNewKey(km, 0, "OUR_pick", LA_KM_SEL_UI_EXTRA, 0, LA_R_MOUSE_DOWN, 0, 0);
 
     laSetMenuBarTemplates(ourui_MenuButtons, laui_DefaultMenuExtras, "OurPaint v0.1");
+
+    laSaveProp("our");
 }
 
 

+ 12 - 2
ourpaint.h

@@ -31,6 +31,7 @@ STRUCTURE(OurCanvasDraw){
 STRUCTURE(OurTexTile){
     tnsTexture* Texture;
     uint16_t* Data;
+    int row,col;
 };
 STRUCTURE(OurLayer){
     laListItem Item;
@@ -39,6 +40,16 @@ STRUCTURE(OurLayer){
     OurTexTile** TexTiles[OUR_TEX_TILES_PER_ROW];
 };
 
+STRUCTURE(OurLayerWrite){
+    unsigned char* data;
+    size_t NextData, MaxData;
+};
+
+STRUCTURE(OurLayerRead){
+    unsigned char* data;
+    size_t NextData;
+};
+
 STRUCTURE(OurBrush){
     laListItem Item;
     laSafeString Name;
@@ -68,7 +79,6 @@ STRUCTURE(OurPaint){
 
     laListHandle Layers;
     OurLayer*    CurrentLayer;
-
     laListHandle Brushes;
     OurBrush*    CurrentBrush;
     OurDab* Dabs; int NextDab,MaxDab;
@@ -95,7 +105,7 @@ STRUCTURE(OurPaint){
     real BorderAlpha;
 
     uint16_t *ImageBuffer;
-    int ImageW,ImageH,ImageX,ImageY,LoadX,LoadY;
+    int ImageW,ImageH,ImageX,ImageY,LoadX,LoadY,TempLoadX,TempLoadY;
 
     void* icc_LinearsRGB; int iccsize_LinearsRGB;
     void* icc_sRGB; int iccsize_sRGB;