|
@@ -1520,6 +1520,71 @@ void our_ReadWidgetColor(laCanvasExtra*e,int x,int y){
|
|
|
color[0]*=color[3];color[1]*=color[3];color[2]*=color[3];tnsVectorSet3v(Our->CurrentColor,color);
|
|
|
}
|
|
|
|
|
|
+int our_RenderThumbnail(uint8_t** buf, int* sizeof_buf){
|
|
|
+ int x=INT_MAX,y=INT_MAX,w=-INT_MAX,h=-INT_MAX;
|
|
|
+ for(OurLayer* l=Our->Layers.pFirst;l;l=l->Item.pNext){
|
|
|
+ our_LayerClearEmptyTiles(l);
|
|
|
+ our_LayerEnsureImageBuffer(l,1);
|
|
|
+ if(Our->ImageX<x) x=Our->ImageX; if(Our->ImageY<y) y=Our->ImageY;
|
|
|
+ if(Our->ImageW>w) w=Our->ImageW; if(Our->ImageH>h) h=Our->ImageH;
|
|
|
+ }
|
|
|
+ if(w<=0||h<=0) return 0;
|
|
|
+ real r = (real)(TNS_MAX2(w,h))/400.0f;
|
|
|
+ int use_w=w/r, use_h=h/r;
|
|
|
+
|
|
|
+ tnsOffscreen* off = tnsCreate2DOffscreen(GL_RGBA,use_w,use_h,0,0,0);
|
|
|
+ tnsDrawToOffscreen(off,1,0);
|
|
|
+ tnsViewportWithScissor(0, 0, use_w, use_h);
|
|
|
+ tnsResetViewMatrix();tnsResetModelMatrix();tnsResetProjectionMatrix();
|
|
|
+ tnsOrtho(x,x+w,y+h,y,-100,100);
|
|
|
+ tnsClearColor(LA_COLOR3(Our->BackgroundColor),1); tnsClearAll();
|
|
|
+ our_CanvasDrawTextures();
|
|
|
+
|
|
|
+ if(Our->ImageBuffer){ free(Our->ImageBuffer); }
|
|
|
+ int bufsize=w*h*sizeof(uint16_t)*4;
|
|
|
+ Our->ImageBuffer=malloc(bufsize);
|
|
|
+ tnsBindTexture(off->pColor[0]); glPixelStorei(GL_PACK_ALIGNMENT, 2);
|
|
|
+ glGetTextureSubImage(off->pColor[0]->GLTexHandle, 0, 0, 0, 0, use_w, use_h, 1, GL_RGBA, GL_UNSIGNED_SHORT, bufsize, Our->ImageBuffer);
|
|
|
+
|
|
|
+ tnsDrawToScreen();
|
|
|
+ tnsDelete2DOffscreen(off);
|
|
|
+
|
|
|
+ our_ImageConvertForExport(OUR_EXPORT_BIT_DEPTH_8,OUR_EXPORT_COLOR_MODE_CLAY);
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+ OurLayerWrite LayerWrite={0};
|
|
|
+ arrEnsureLength(&LayerWrite.data,0,&LayerWrite.MaxData,sizeof(unsigned char));
|
|
|
+ png_set_write_fn(png_ptr,&LayerWrite,_our_png_write,0);
|
|
|
+
|
|
|
+ png_set_IHDR(png_ptr, info_ptr,use_w,use_h,8,PNG_COLOR_TYPE_RGBA,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_BASE,PNG_FILTER_TYPE_BASE);
|
|
|
+ png_write_info(png_ptr, info_ptr);
|
|
|
+ png_set_swap(png_ptr);
|
|
|
+
|
|
|
+ uint8_t* data=Our->ImageBuffer;
|
|
|
+ for(int i=0;i<use_h;i++){
|
|
|
+ png_write_row(png_ptr,&data[use_w*i*4]);
|
|
|
+ }
|
|
|
+ png_write_end(png_ptr, info_ptr);
|
|
|
+ png_destroy_write_struct(&png_ptr, &info_ptr);
|
|
|
+
|
|
|
+ *buf=LayerWrite.data; *sizeof_buf=LayerWrite.NextData;
|
|
|
+
|
|
|
+ free(Our->ImageBuffer);
|
|
|
+ Our->ImageBuffer=0;
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+int our_GetFileThumbnail(char* file, uint8_t** buf, int* sizeof_buf){
|
|
|
+ laUDF* udf = laOpenUDF(file,0,0,0);
|
|
|
+
|
|
|
+ if(udf){
|
|
|
+ laExtractProp(udf,"our.thumbnail");
|
|
|
+ laExtractUDF(udf,0,LA_UDF_MODE_APPEND); laCloseUDF(udf);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void our_StartCropping(OurCanvasDraw* cd){
|
|
|
if(cd->CanvasDownX<Our->X){
|
|
|
if(cd->CanvasDownY<Our->Y-Our->H){ cd->AtCrop=OUR_AT_CROP_BL; }
|
|
@@ -1997,6 +2062,14 @@ int ourinv_ClearEmptyTiles(laOperator* a, laEvent* e){
|
|
|
return LA_FINISHED;
|
|
|
}
|
|
|
|
|
|
+void* ourgetraw_FileThumbnail(void* unused, int* r_size, int* r_is_copy){
|
|
|
+ void* buf=0;
|
|
|
+ if(our_RenderThumbnail(&buf, r_size)){ *r_is_copy=1; return buf; }
|
|
|
+ *r_is_copy=0; return 0;
|
|
|
+}
|
|
|
+void oursetraw_FileThumbnail(void* unused, void* data, int DataSize){
|
|
|
+ return;
|
|
|
+}
|
|
|
void ourget_CanvasIdentifier(void* unused, char* buf, char** ptr){
|
|
|
*ptr="Main canvas";
|
|
|
}
|
|
@@ -2195,6 +2268,25 @@ void ourui_ToolExtras(laUiList *uil, laPropPack *pp, laPropPack *actinst, laColu
|
|
|
//laShowLabel(uil, c, MAIN.MenuProgramName, 0, 0)->Expand=1;
|
|
|
}
|
|
|
|
|
|
+int ourProcessInitArgs(int argc, char* argv[]){
|
|
|
+ if(argc == 4 && strstr(argv[1],"--t")==argv[1]){
|
|
|
+ FILE* fp=fopen(argv[2],"rb"); if(!fp){ printf("Can't open file %s\n",argv[2]); return -1; }
|
|
|
+ void* data=0; size_t size=0;
|
|
|
+ if(laExtractQuickRaw(fp,"our.thumbnail",&data,&size)){
|
|
|
+ FILE* thumb = fopen(argv[3],"wb");
|
|
|
+ if(thumb){
|
|
|
+ fwrite(data, size, 1, thumb);
|
|
|
+ fclose(thumb);
|
|
|
+ }
|
|
|
+ free(data);
|
|
|
+ }else{
|
|
|
+ printf("File doesn't have a thumbnail.\n",argv[2]);
|
|
|
+ }
|
|
|
+ fclose(fp);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void ourPreFrame(){
|
|
|
if(MAIN.GraphNeedsRebuild){ ourRebuildBrushEval(); }
|
|
|
}
|
|
@@ -2280,6 +2372,7 @@ void ourRegisterEverything(){
|
|
|
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);
|
|
|
+ laAddRawProperty(pc,"thumbnail","Thumbnail","Thumbnail of this file",0,0,ourgetraw_FileThumbnail,oursetraw_FileThumbnail,LA_READ_ONLY);
|
|
|
laAddSubGroup(pc,"canvas","Canvas","OurPaint canvas","our_canvas",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
|
|
|
laAddSubGroup(pc,"tools","Tools","OurPaint tools","our_tools",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
|
|
|
laAddSubGroup(pc,"preferences","Preferences","OurPaint preferences","our_preferences",0,0,0,0,0,0,0,0,0,0,0,LA_UDF_LOCAL);
|
|
@@ -2502,7 +2595,8 @@ void ourRegisterEverything(){
|
|
|
|
|
|
ourRegisterNodes();
|
|
|
|
|
|
- laSaveProp("our.canvas");
|
|
|
+ laManagedSaveProp* msp= laSaveProp("our.canvas");
|
|
|
+ laSaveAlongside(msp,"our.thumbnail");
|
|
|
laSaveProp("our.tools");
|
|
|
|
|
|
laGetSaverDummy(Our,Our->CanvasSaverDummyProp);
|