Image Stamping patch by Diego (and peach request)- stamps image info into metadata...
authorCampbell Barton <ideasman42@gmail.com>
Sat, 20 Oct 2007 16:17:27 +0000 (16:17 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 20 Oct 2007 16:17:27 +0000 (16:17 +0000)
draws into the
frame.

This patch includes some changes I made...
* use blenders bitmap fonts (rather then own fonts)
* select font size
* user interface layout changes
* Marker as another image stamp option

Also added some new API calls
BMF_GetFontHeight(font);
BMF_DrawStringBuf(...);  - so we can draw text into an imbuf's image buffer.
get_frame_marker(frame) - get the last marker from the frame.
IMB_rectfill_area(...) - fill in an image buffer with a rectangle area of color.

TODO - draw stamp info in 3d view, at the moment it just displays in the animation.

23 files changed:
intern/bmfont/BMF_Api.h
intern/bmfont/intern/BMF_Api.cpp
intern/bmfont/intern/BMF_BitmapFont.cpp
intern/bmfont/intern/BMF_BitmapFont.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/image.c
source/blender/blenloader/intern/readfile.c
source/blender/blenpluginapi/iff.h
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/IMB_imginfo.h
source/blender/imbuf/intern/imginfo.c
source/blender/imbuf/intern/png.c
source/blender/imbuf/intern/rectop.c
source/blender/imbuf/intern/thumbs.c
source/blender/include/BSE_time.h
source/blender/makesdna/DNA_scene_types.h
source/blender/src/buttons_scene.c
source/blender/src/buttons_shading.c
source/blender/src/drawview.c
source/blender/src/editmesh_tools.c
source/blender/src/edittime.c
source/blender/src/transform_constraints.c

index 5900ea85ec79d9c6c4c46bcdb7b70b1cb017caee..1b4a4ee3129ff0aa7596865b56ac97bc9b75fca6 100644 (file)
@@ -109,6 +109,11 @@ void BMF_GetStringBoundingBox(BMF_Font* font, char* str, float*llx, float *lly,
  */
 void BMF_GetFontBoundingBox(BMF_Font* font, int *xmin_r, int *ymin_r, int *xmax_r, int *ymax_r);
 
+/**
+ * Same as GetFontBoundingBox but only returns the height
+ */
+int BMF_GetFontHeight(BMF_Font* font);
+
 /**
  * Convert the given @a font to a texture, and return the GL texture
  * ID of the texture. If the texture ID is bound, text can
@@ -134,6 +139,23 @@ int BMF_GetFontTexture(BMF_Font* font);
  */
 void BMF_DrawStringTexture(BMF_Font* font, char* string, float x, float y, float z);
 
+       /**
+ * Draw the given @a string at the point @a xpos, @a ypos using
+ * char and float buffers.
+ * 
+ * @param string The c-string to draw.
+ * @param xpos The x coordinate to start drawing at.
+ * @param ypos The y coordinate to start drawing at.
+ * @param fgcol The forground color.
+ * @param bgcol The background color.
+ * @param buf Unsigned char image buffer, when NULL to not operate on it.
+ * @param fbuf float image buffer, when NULL to not operate on it.
+ * @param w image buffer width.
+ * @param h image buffer height.
+        */
+void BMF_DrawStringBuf(BMF_Font* font, char *str, int posx, int posy, float *col, unsigned char *buf, float *fbuf, int w, int h);
+
+
 #ifdef __cplusplus
 }
 #endif
index 176ef452fdc2465d0dbfa30e828e519e6d5f13d9..eaa8ffb939d624cca906263556f6dba9cba3fc9b 100644 (file)
@@ -164,6 +164,12 @@ void BMF_GetFontBoundingBox(BMF_Font* font, int *xmin_r, int *ymin_r, int *xmax_
        ((BMF_BitmapFont*)font)->GetFontBoundingBox(*xmin_r, *ymin_r, *xmax_r, *ymax_r);
 }
 
+int BMF_GetFontHeight(BMF_Font* font)
+{
+       if (!font) return -1;
+       return ((BMF_BitmapFont*)font)->GetFontHeight();
+}
+
 int BMF_GetFontTexture(BMF_Font* font) {
        if (!font) return -1;
        return ((BMF_BitmapFont*)font)->GetTexture();
@@ -173,3 +179,8 @@ void BMF_DrawStringTexture(BMF_Font* font, char *string, float x, float y, float
        if (!font) return;
        ((BMF_BitmapFont*)font)->DrawStringTexture(string, x, y, z);
 }
+
+void BMF_DrawStringBuf(BMF_Font* font, char *str, int posx, int posy, float *col, unsigned char *buf, float *fbuf, int w, int h) {
+       if (!font) return;
+       ((BMF_BitmapFont*)font)->DrawStringBuf(str, posx, posy, col, buf, fbuf, w, h);
+}
index 8be4ff19a4f1fa7bb7d4a99d90298aa49abb2a46..99ded41007f39f86daaed7c4c6358f9215c80155 100644 (file)
  * Copyright (C) 2001 NaN Technologies B.V.
  */
 
+
+#include <stdio.h>
+
+
+
 #include <string.h>
 
 #ifdef HAVE_CONFIG_H
@@ -115,6 +120,11 @@ void BMF_BitmapFont::GetFontBoundingBox(int & xMin, int & yMin, int & xMax, int
        yMax = m_fontData->ymax;
 }
 
+int BMF_BitmapFont::GetFontHeight( void )
+{
+       return m_fontData->ymax - m_fontData->ymin;
+}
+
 void BMF_BitmapFont::GetStringBoundingBox(char* str, float*llx, float *lly, float *urx, float *ury)
 {
        unsigned char c;
@@ -229,3 +239,83 @@ void BMF_BitmapFont::DrawStringTexture(char *str, float x, float y, float z)
        }
        glEnd();
 }
+
+#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
+
+
+void BMF_BitmapFont::DrawStringBuf(char *str, int posx, int posy, float *col, unsigned char *buf, float *fbuf, int w, int h)
+{
+       int x, y;
+       
+       if (buf==0 && fbuf==0)
+               return;
+
+       /*offset for font*/
+       posx -= m_fontData->xmin;
+       posy -= m_fontData->ymin;
+       
+       if (buf) {
+               unsigned char colch[3];
+               unsigned char *max, *pixel;
+               unsigned char c;
+               
+               for (x=0; x<3; x++) {
+                       colch[x] = FTOCHAR(col[x]);
+               }
+               
+               max = buf + (4 * (w * h));
+               while ((c = (unsigned char) *str++)) {
+                       BMF_CharData & cd = m_fontData->chars[c];
+                       if (cd.data_offset != -1) { 
+                               for (y = 0; y < cd.height; y++) {
+                                       unsigned char* chrRow = &m_fontData->bitmap_data[cd.data_offset + ((cd.width+7)/8)*y];
+                                       for (x = cd.xorig; x < cd.width; x++) {
+                                               pixel = buf + 4 * (((posy + y) * w) + (posx + x));
+                                               if ((pixel < max) && (pixel > buf)) {
+                                                       int byteIdx = x/8;
+                                                       int bitIdx = 7 - (x%8);
+                                                       
+                                                       if (chrRow[byteIdx]&(1<<bitIdx)) {
+                                                               pixel[0] = colch[0];
+                                                               pixel[1] = colch[1];
+                                                               pixel[2] = colch[2];
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       posx += cd.advance;
+               }
+       }
+       
+       if (fbuf) {
+               float *pixel, *max;
+               unsigned char c;
+               int x, y;
+               
+               max = fbuf + (4 * (w * h));
+               
+               while ((c = (unsigned char) *str++)) {
+                       BMF_CharData & cd = m_fontData->chars[c];
+                       if (cd.data_offset != -1) { 
+                               for (y = 0; y < cd.height; y++) {
+                                       unsigned char* chrRow = &m_fontData->bitmap_data[cd.data_offset + ((cd.width+7)/8)*y];
+                                       for (x = cd.xorig; x < cd.width; x++) {
+                                               pixel = fbuf + 4 * (((posy + y - cd.yorig) * w) + (posx + x));
+                                               if ((pixel < max) && (pixel > fbuf)) {
+                                                       int byteIdx = x/8;
+                                                       int bitIdx = 7 - (x%8);
+                                                       
+                                                       if (chrRow[byteIdx]&(1<<bitIdx)) {
+                                                               pixel[0] = col[0];
+                                                               pixel[1] = col[1];
+                                                               pixel[2] = col[2];
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       posx += cd.advance;
+               }
+       }
+}
index e8e0abc0561d09b79b03810f2909ca43cdcaee42..986de2bb399debfc38e830bb2ac871881d2cf286 100644 (file)
@@ -78,6 +78,11 @@ public:
         */
        void GetFontBoundingBox(int & xMin, int & yMin, int & xMax, int & yMax);
        
+       /**
+        * Return the bounding box height of the font.
+        */
+       int GetFontHeight(void);
+       
        /**
         * Returns the bounding box of a string of characters.
         * @param font  The font to use.
@@ -113,6 +118,21 @@ public:
         */
        void DrawStringTexture(char* string, float x, float y, float z);
        
+       /**
+        * Draw the given @a string at the point @a xpos, @a ypos using
+        * char and float buffers.
+        * 
+        * @param string The c-string to draw.
+        * @param xpos The x coordinate to start drawing at.
+        * @param ypos The y coordinate to start drawing at.
+        * @param col The forground color.
+        * @param buf Unsigned char image buffer, when NULL to not operate on it.
+        * @param fbuf float image buffer, when NULL to not operate on it.
+        * @param w image buffer width.
+        * @param h image buffer height.
+        */
+       void DrawStringBuf(char *str, int posx, int posy, float *col, unsigned char *buf, float *fbuf, int w, int h);
+       
 protected:
        /** Pointer to the font data. */
         BMF_FontData* m_fontData;
index 328d9775deb3ca4bf18f8271f8fc39c54b3bf354..73af56b9123b28238174a3515a6a2c5e0d3bbfda 100644 (file)
@@ -44,7 +44,7 @@ struct ListBase;
 struct MemFile;
 
 #define BLENDER_VERSION                        245
-#define BLENDER_SUBVERSION             4
+#define BLENDER_SUBVERSION             5
 
 #define BLENDER_MINVERSION             240
 #define BLENDER_MINSUBVERSION  0
index 58f96491a1bec90ac103bc5dd921dc76f2c39192..204e956dbc8bedab5965b50089996ad5b6f27cc0 100644 (file)
@@ -46,6 +46,7 @@ struct anim;
 /* call from library */
 void   free_image(struct Image *me);
 
+void   BKE_stamp(struct ImBuf *ibuf);
 int            BKE_write_ibuf(struct ImBuf *ibuf, char *name, int imtype, int subimtype, int quality);
 void   BKE_makepicstring(char *string, char *base, int frame, int imtype);
 void   BKE_add_image_extension(char *string, int imtype);
index ff84b3c08f82fb96dceffdb6a7296d5801c11b47..708309934b592c4e831b9173d4e560b324d5775d 100644 (file)
@@ -52,6 +52,7 @@
 #include "DNA_image_types.h"
 #include "DNA_packedFile_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_camera_types.h"
 #include "DNA_texture_types.h"
 #include "DNA_userdef_types.h"
 
 /* bad level; call to free_realtime_image */
 #include "BKE_bad_level_calls.h"       
 
+/* for stamp drawing to an image */
+#include "../bmfont/BMF_Api.h"
+
+#include "blendef.h"
+#include "BSE_time.h"
+
 /* max int, to indicate we don't store sequences in ibuf */
 #define IMA_NO_INDEX   0x7FEFEFEF
 
@@ -770,6 +777,183 @@ void BKE_add_image_extension(char *string, int imtype)
        strcat(string, extension);
 }
 
+void BKE_stamp(struct ImBuf *ibuf)
+{
+       char text[256], infotext[256];
+       int x, y, h, m, s, f;
+       int font_height;
+       int text_width;
+       int text_pad;
+       struct BMF_Font *font;
+       
+       
+#ifndef WIN32
+       struct tm *tl;
+       time_t t;
+#else
+       char sdate[9];
+#endif /* WIN32 */
+
+       if (!ibuf)
+               return;
+       
+       switch (G.scene->r.stamp_font_id) {
+       case 1: /* tiny */
+               font = BMF_GetFont(BMF_kHelveticaBold8);
+               break;
+       case 2: /* small */
+               font = BMF_GetFont(BMF_kHelveticaBold10);
+               break;
+       case 3: /* medium */
+               font = BMF_GetFont(BMF_kScreen12);
+               break;
+       case 0: /* large - default */
+               font = BMF_GetFont(BMF_kScreen15);
+               break;
+       case 4: /* huge */
+               font = BMF_GetFont(BMF_kHelveticaBold14);
+               break;
+       }
+       
+       font_height = BMF_GetFontHeight(font);
+       text_pad = BMF_GetStringWidth(font, " ");
+       
+       IMB_imginfo_change_field (ibuf, "File", G.sce);
+       if (G.scene->r.stamp & R_STAMP_DRAW) {
+               x = 1;
+               y = ibuf->y - font_height;
+               sprintf(text, "File: %s", G.sce);
+               text_width = BMF_GetStringWidth(font, text);
+               IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+               BMF_DrawStringBuf(font, G.sce, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+               x = 1;
+               y -= font_height+1;
+       }
+
+
+       if (G.scene->r.stamp & R_STAMP_TIME) {
+               h= m= s= f= 0;
+               f = (int)(G.scene->r.cfra % G.scene->r.frs_sec);
+               s = (int)(G.scene->r.cfra / G.scene->r.frs_sec);
+
+               if (s) {
+                       m = (int)(s / 60);
+                       s %= 60;
+
+                       if (m) {
+                               h = (int)(m / 60);
+                               m %= 60;
+                       }
+               }
+
+               if (G.scene->r.frs_sec < 100)
+                       sprintf (infotext, "%02d:%02d:%02d.%02d", h, m, s, f);
+               else
+                       sprintf (infotext, "%02d:%02d:%02d.%03d", h, m, s, f);
+               
+               IMB_imginfo_change_field (ibuf, "Time", infotext);
+               
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       sprintf (text, "Time %s", infotext);
+                       text_width = BMF_GetStringWidth(font, text);
+                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+                       x += text_width;
+               }
+       }
+
+       if (G.scene->r.stamp & R_STAMP_FRAME) {
+               sprintf (infotext, "%i", G.scene->r.cfra);
+               IMB_imginfo_change_field (ibuf, "Frame", infotext);
+
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       sprintf (text, "    Frame %s", infotext);
+                       text_width = BMF_GetStringWidth(font, text);
+                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+                       x += BMF_GetStringWidth(font, text);
+               }
+       }
+
+       if (G.scene->r.stamp & R_STAMP_DATE) {
+#ifdef WIN32
+               _strdate (sdate);
+               sprintf (infotext, "%s", sdate);
+#else
+               t = time (NULL);
+               tl = localtime (&t);
+               sprintf (infotext, "%02d-%02d-%02d", tl->tm_mon+1, tl->tm_mday, tl->tm_year-100);
+#endif /* WIN32 */
+               IMB_imginfo_change_field (ibuf, "Date", infotext);
+
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       x = 1;
+                       y = 1;
+                       sprintf (text, "Date %s", infotext);
+                       text_width = BMF_GetStringWidth(font, text);
+                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+                       x += text_width;
+               }
+       }
+
+       if (G.scene->r.stamp & R_STAMP_CAMERA) {
+               sprintf(infotext, ((Camera *) G.scene->camera)->id.name+2);
+               IMB_imginfo_change_field (ibuf, "Camera", infotext);
+
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       sprintf (text, "Camera: %s", infotext);
+                       text_width = BMF_GetStringWidth(font, text);
+                       x = (ibuf->x/2) - (BMF_GetStringWidth(font, text)/2);
+                       y = 1;
+                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+               }
+       }
+
+       if (G.scene->r.stamp & R_STAMP_SCENE) {
+               strcpy(infotext, G.scene->id.name+2);
+               IMB_imginfo_change_field (ibuf, "Scene", infotext);
+
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       sprintf (text, "Scene: %s", infotext);
+                       text_width = BMF_GetStringWidth(font, text);
+                       x = ibuf->x - (BMF_GetStringWidth(font, text)+1+text_pad);
+                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+               }
+       }
+       
+       if (G.scene->r.stamp & R_STAMP_NOTE) {
+               IMB_imginfo_change_field (ibuf, "Note", G.scene->r.stamp_udata);
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       x = 1;
+                       y = font_height+1;
+                       text_width = BMF_GetStringWidth(font, G.scene->r.stamp_udata);
+                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+                       BMF_DrawStringBuf(font, G.scene->r.stamp_udata, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+               }
+       }
+       
+       if (G.scene->r.stamp & R_STAMP_MARKER) {
+               TimeMarker *marker = get_frame_marker(CFRA);
+               
+               if (marker) strcpy(infotext, marker->name);
+               else            strcpy(infotext, "None");
+               
+               IMB_imginfo_change_field (ibuf, "Marker", infotext);
+               
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       sprintf (text, "Marker: %s", infotext);
+                       x = 1;
+                       y = ibuf->y - (font_height+1)*3;
+                       text_width = BMF_GetStringWidth(font, text);
+                       IMB_rectfill_area(ibuf, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+                       BMF_DrawStringBuf(font, text, x, y, G.scene->r.fg_stamp, (unsigned char *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y);
+               }
+       }
+}
 
 int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quality)
 {
@@ -830,7 +1014,10 @@ int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quali
        }
        
        BLI_make_existing_file(name);
-       
+
+       if(G.scene->r.scemode & R_STAMP_INFO)
+               BKE_stamp(ibuf);
+
        ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
        if (ok == 0) {
                perror(name);
@@ -1254,7 +1441,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
                        BLI_convertstringcode(str, G.sce, cfra);
                
                /* read ibuf */
-               ibuf = IMB_loadiffname(str, IB_rect|IB_multilayer);
+               ibuf = IMB_loadiffname(str, IB_rect|IB_multilayer|IB_imginfo);
        }
        
        if (ibuf) {
index 487cce9e44f68f1ddcc53e631d06845daaf7c146..a58593114702ea169079b9fc00c2b4ac73f2f22b 100644 (file)
@@ -6764,7 +6764,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        ((ArmatureModifierData*)md)->deformflag |= ARM_DEF_B_BONE_REST;
        }
 
-
+       if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 5)) {
+               /* foreground color needs to be somthing other then black */
+               Scene *sce;
+               for(sce= main->scene.first; sce; sce=sce->id.next) {
+                       sce->r.fg_stamp[0] = sce->r.fg_stamp[1] = sce->r.fg_stamp[2] = 0.8;
+               }
+       }
+       
+       
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
index 8e5b538eda6bae6072ab9bf92713997417167019..f63f753e5539f6907a523001d2455ed11636ed51 100644 (file)
@@ -208,6 +208,7 @@ LIBEXPORT void IMB_rectcpy(struct ImBuf *dbuf, struct ImBuf *sbuf,
        int destx, int desty, int srcx, int srcy, int width, int height);
 
 LIBEXPORT void IMB_rectfill(struct ImBuf *drect, float col[4]);
+LIBEXPORT void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, int y2);
 
 #endif /* IFF_H */
 
index 2ca21e548c470f9f6be9c74426c6ec32659b4019..4d91a82a58f8c45b3d0adaabd9ac0aa419da018b 100644 (file)
@@ -545,6 +545,10 @@ void IMB_freezbuffloatImBuf(struct ImBuf * ibuf);
  * @attention Defined in rectop.c
  */
 void IMB_rectfill(struct ImBuf *drect, float col[4]);
+void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, int y2);
+
+/* defined in imginfo.c */
+int IMB_imginfo_change_field(struct ImBuf *img, const char *key, const char *field);
 
 /* exported for image tools in blender, to quickly allocate 32 bits rect */
 short imb_addrectImBuf(struct ImBuf * ibuf);
index c8e9005619cad5679ff4fb4eaffcf2ffe868c67d..e82cc5f32af6b98e1b4708d781970f7bfe817cf3 100644 (file)
@@ -74,6 +74,12 @@ int IMB_imginfo_get_field(struct ImBuf* img, const char* key, char* value, int l
  */
 int IMB_imginfo_add_field(struct ImBuf* img, const char* key, const char* field);
 
+/** delete the key/field par in the ImgInfo struct.
+ * @param img - the ImBuf that contains the image data
+ * @param key - the key of the field
+ * @return - 1 (true) if delete the key/field, 0 (false) otherwise
+ */
+int IMB_imginfo_del_field(struct ImBuf *img, const char *key);
 
 #endif /* _IMB_IMGINFO_H */
 
index 59fbd2f7200a5cbc60551ebd5d08479ed40b2e63..37bde9e5ac3065927093755efa819fd34dad42cd 100644 (file)
@@ -107,3 +107,52 @@ int IMB_imginfo_add_field(struct ImBuf* img, const char* key, const char* field)
        return 1;
 }
 
+int IMB_imginfo_del_field(struct ImBuf *img, const char *key)
+{
+       ImgInfo *p, *p1;
+
+       if ((!img) || (!img->img_info))
+               return (0);
+
+       p = img->img_info;
+       p1 = NULL;
+       while (p) {
+               if (!strcmp (key, p->key)) {
+                       if (p1)
+                               p1->next = p->next;
+                       else
+                               img->img_info = p->next;
+
+                       MEM_freeN(p->key);
+                       MEM_freeN(p->value);
+                       MEM_freeN(p);
+                       return (1);
+               }
+               p1 = p;
+               p = p->next;
+       }
+       return (0);
+}
+
+int IMB_imginfo_change_field(struct ImBuf *img, const char *key, const char *field)
+{
+       ImgInfo *p;
+
+       if (!img)
+               return (0);
+
+       if (!img->img_info)
+               return (IMB_imginfo_add_field (img, key, field));
+
+       p = img->img_info;
+       while (p) {
+               if (!strcmp (key, p->key)) {
+                       MEM_freeN (p->value);
+                       p->value = BLI_strdup (field);
+                       return (1);
+               }
+               p = p->next;
+       }
+
+       return (IMB_imginfo_add_field (img, key, field));
+}
index bb48ff71bff6cadf9ad59ea973e90505db2243ab..c77ff7ea56f7e647777ce2abac1518969f054449 100644 (file)
@@ -236,6 +236,7 @@ short imb_savepng(struct ImBuf *ibuf, char *name, int flags)
                iptr = ibuf->img_info;
                num_text = 0;
                while (iptr) {
+                       
                        imginfo[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
                        imginfo[num_text].key = iptr->key;
                        imginfo[num_text].text = iptr->value;
index 85c5e07bb8e8fa269458ad5b8eeb4382db8c51b0..55cd4b9b6a1f846bda14d32b881037ffdf8b77a5 100644 (file)
@@ -517,3 +517,56 @@ void IMB_rectfill(struct ImBuf *drect, float col[4])
        }       
 }
 
+/* maybe we should use BKE_utildefines.h */
+#define FTOCHAR(val) (val<=0.0f ? 0: (val>=1.0f ? 255: (char)(255.99f*val)))
+#define CLAMP(a, b, c)         if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c)
+#define SWAP(type, a, b)        { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
+void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, int y2)
+{
+       int i, j;
+       
+       if ((!ibuf) || (!col))
+               return;
+       
+       /* sanity checks for coords */
+       CLAMP(x1, 0, ibuf->x);
+       CLAMP(x2, 0, ibuf->x);
+       CLAMP(y1, 0, ibuf->y);
+       CLAMP(y2, 0, ibuf->y);
+
+       if (x1>x2) SWAP(int,x1,x2);
+       if (y1>y2) SWAP(int,y1,y2);
+       if (x1==x2 || y1==y2) return;
+       
+       if (ibuf->rect) {
+               unsigned char *img, *pixel; 
+               unsigned char chr, chg, chb;
+       
+               chr = FTOCHAR(col[0]);
+               chg = FTOCHAR(col[1]);
+               chb = FTOCHAR(col[2]);
+               
+               img = (unsigned char *) ibuf->rect;
+               for (j = 0; j < y2-y1; j++) {
+                       for (i = 0; i < x2-x1; i++) {
+                               pixel = img + 4 * (((y1 + j) * ibuf->x) + (x1 + i));
+                               pixel[0] = chr;
+                               pixel[1] = chg;
+                               pixel[2] = chb;
+                       }
+               }
+       }
+       
+       if (ibuf->rect_float) {
+               float *img, *pixel;
+               img = ibuf->rect_float;
+               for (j = 0; j < y2-y1; j++) {
+                       for (i = 0; i < x2-x1; i++) {
+                               pixel = img + 4 * (((y1 + j) * ibuf->x) + (x1 + i));
+                               pixel[0] = col[0];
+                               pixel[1] = col[1];
+                               pixel[2] = col[2];
+                       }
+               }
+       }
+}
index 493b0968f55bb63d02602ee72b1141ee456a494c..131d2ef38f7c84f169b42d3e9e214c0964dc91c7 100644 (file)
@@ -281,7 +281,7 @@ ImBuf* IMB_thumb_create(const char* dir, const char* file, ThumbSize size, Thumb
                        if (THB_SOURCE_IMAGE == source) {
                                BLI_getwdN(wdir);
                                chdir(dir);
-                               img = IMB_loadiffname(file, IB_rect);
+                               img = IMB_loadiffname(file, IB_rect | IB_imginfo);
                                if (img != NULL) {
                                        stat(file, &info);
                                        sprintf(mtime, "%ld", info.st_mtime);
@@ -324,13 +324,13 @@ ImBuf* IMB_thumb_create(const char* dir, const char* file, ThumbSize size, Thumb
                        IMB_scaleImBuf(img, ex, ey);
                }
                sprintf(desc, "Thumbnail for %s", uri);
-               IMB_imginfo_add_field(img, "Description", desc);
-               IMB_imginfo_add_field(img, "Software", "Blender");
-               IMB_imginfo_add_field(img, "Thumb::URI", uri);
-               IMB_imginfo_add_field(img, "Thumb::MTime", mtime);
+               IMB_imginfo_change_field(img, "Description", desc);
+               IMB_imginfo_change_field(img, "Software", "Blender");
+               IMB_imginfo_change_field(img, "Thumb::URI", uri);
+               IMB_imginfo_change_field(img, "Thumb::MTime", mtime);
                if (THB_SOURCE_IMAGE == source) {
-                       IMB_imginfo_add_field(img, "Thumb::Image::Width", cwidth);
-                       IMB_imginfo_add_field(img, "Thumb::Image::Height", cheight);
+                       IMB_imginfo_change_field(img, "Thumb::Image::Width", cwidth);
+                       IMB_imginfo_change_field(img, "Thumb::Image::Height", cheight);
                }
                img->ftype = PNG;
                img->depth = 32;                
index c7f235bccbd3d4333c41c8ca74505dd540b09ffd..d5cff9f5e5fcc5d28101ee9205f969eeb2d148df 100644 (file)
@@ -55,6 +55,7 @@ void add_marker_to_cfra_elem(struct ListBase *lb, struct TimeMarker *marker, sho
 void make_marker_cfra_list(struct ListBase *lb, short only_sel);
 
 void draw_markers_timespace(int lines);
+TimeMarker *get_frame_marker(int frame);
 
 /* ******** Animation - Preview Range ************* */
 void anim_previewrange_set(void);
index 2ba5ef5437c5c0b2d9cdefc9a5280ad69c33cde6..56b44c3ec978cfc6e390b5d14c674f552d450f68 100644 (file)
@@ -278,6 +278,16 @@ typedef struct RenderData {
        /* paths to backbufffer, output, ftype */
        char backbuf[160], pic[160], ftype[160];
 
+       /* stamps flags. */
+       int stamp;
+       short stamp_font_id, pad3; /* select one of blenders bitmap fonts */
+
+       /* stamp info user data. */
+       char stamp_udata[160];
+
+       /* foreground/background color. */
+       float fg_stamp[4];
+       float bg_stamp[4];
 } RenderData;
 
 
@@ -517,7 +527,17 @@ typedef struct Scene {
 #define R_COMP_FREE                    0x0800
 #define R_NO_IMAGE_LOAD                0x1000
 #define R_NO_TEX               0x2000
-
+#define R_STAMP_INFO           0x4000
+
+/* r->stamp */
+#define R_STAMP_TIME   0x0001
+#define R_STAMP_FRAME  0x0002
+#define R_STAMP_DATE   0x0004
+#define R_STAMP_CAMERA 0x0008
+#define R_STAMP_SCENE  0x0010
+#define R_STAMP_NOTE   0x0020
+#define R_STAMP_DRAW   0x0040 /* draw in the image */
+#define R_STAMP_MARKER 0x0080
 
 /* alphamode */
 #define R_ADDSKY               0
index c319485cb0ff876a410cac9e0152faf1fcc9a46e..939c3b561e3c49c5410077057ea1cda2f23d7604 100644 (file)
@@ -1526,6 +1526,71 @@ static void render_panel_ffmpeg_audio(void)
 }
 #endif
 
+static void render_panel_stamp(void)
+{
+       uiBlock *block;
+       int yofs, xofs;
+
+
+       block= uiNewBlock (&curarea->uiblocks, "render_panel_stamp", UI_EMBOSS, UI_HELV, curarea->win);
+       uiNewPanelTabbed ("Format", "Render");
+       if(uiNewPanel (curarea, block, "Stamp", "Render", 960, 0, 318, 204)==0) return;
+
+       if (G.scene->r.scemode & R_STAMP_INFO) {
+               yofs = 0;
+               xofs = 550;uiBlockBeginAlign(block);
+               
+               uiBlockBeginAlign(block);
+               uiDefButBitI(block, TOG, R_STAMP_NOTE, B_REDR, "Note", xofs, yofs, 100, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp user data");
+               uiDefBut(block, TEX, B_NOP, "", xofs+100, yofs, 200, 19, &G.scene->r.stamp_udata, 0.0, 128.0, 100, 0, "User Note");
+               uiBlockEndAlign(block);
+               yofs += 30; /* gap */
+               
+               
+               yofs += 100;
+               // Order is important for alligning ... grr
+               uiBlockBeginAlign(block);
+               uiDefButBitI(block, TOG, R_STAMP_SCENE, B_REDR, "Scene", xofs, yofs, 100, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp scene name");
+               yofs -= 20;
+               uiDefButBitI(block, TOG, R_STAMP_CAMERA, B_REDR, "Camera", xofs, yofs, 100, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp camera name");
+               yofs -= 20;
+               uiDefButBitI(block, TOG, R_STAMP_DATE, B_REDR, "Date", xofs, yofs, 100, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp date");
+               yofs -= 20;
+               uiDefButBitI(block, TOG, R_STAMP_TIME, B_REDR, "Time", xofs, yofs, 100, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp time (HH:MM:SS)");
+               yofs -= 20;
+               uiDefButBitI(block, TOG, R_STAMP_FRAME, B_REDR, "Frame", xofs, yofs, 100, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp frame number");
+               yofs -= 20;
+               uiDefButBitI(block, TOG, R_STAMP_MARKER, B_REDR, "Marker", xofs, yofs, 100, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp the last marker");
+               uiBlockEndAlign(block);
+               yofs += 100;
+               
+               /* draw font selector */
+               if (G.scene->r.stamp & R_STAMP_DRAW) {
+                       uiDefButS(block, MENU, B_REDR, "Stamp Font Size%t|Tiny Text%x1|Small Text%x2|Medium Text%x3|Large Text%x0|Extra Large Text%x4|",
+                                       xofs+110, yofs, 190, 19, &G.scene->r.stamp_font_id, 0, 0, 0, 0, "Choose rendering engine");
+                       
+                       /* draw fg/bg next to the scene */
+                       yofs -= 25;
+                       uiDefBut(block, LABEL, 0, "Text Color", xofs+110, yofs, 80, 19, 0, 0, 0, 0, 0, "");
+                       uiDefBut(block, LABEL, 0, "Background", xofs+205, yofs, 80, 19, 0, 0, 0, 0, 0, "");
+                       yofs -= 20;
+                       uiDefButF(block, COL, B_NOP, "", xofs+110, yofs, 90, 19, G.scene->r.fg_stamp, 0, 0, 0, 0, "Foreground text color");
+                       uiDefButF(block, COL, B_NOP, "", xofs+210, yofs, 90, 19, G.scene->r.bg_stamp, 0, 0, 0, 0, "Background color");
+                       yofs += 75;
+               } else {
+                       yofs += 30;
+               }
+               
+               uiDefButBitS(block, TOG, R_STAMP_INFO, B_REDR, "Enable Stamp", xofs, yofs, 100, 20, &G.scene->r.scemode, 0, 0, 0, 0, "Disable stamp info in images metadata");
+               uiDefButBitI(block, TOG, R_STAMP_DRAW, B_REDR, "Draw Stamp", xofs+110, yofs, 190, 20, &G.scene->r.stamp, 0, 0, 0, 0, "Draw the stamp info into each frame");
+               yofs += 20;
+       }
+       else {
+               uiDefButBitS(block, TOG, R_STAMP_INFO, B_REDR, "Enable Stamp", xofs, 142, 100, 20, &G.scene->r.scemode, 0, 0, 0, 0, "Enable stamp info to image metadata");
+               yofs += 20;
+               uiDefBut(block, LABEL, 0, "", xofs, yofs, 300, 19, 0, 0, 0, 0, 0, "");
+       }
+}
 
 static void render_panel_format(void)
 {
@@ -1927,6 +1992,7 @@ void render_panels()
        render_panel_bake();
 
        render_panel_format();
+       render_panel_stamp();
 #ifdef WITH_FFMPEG
        if (G.scene->r.imtype == R_FFMPEG) {
                   render_panel_ffmpeg_video();
index e5026f6f64ea8e9708a4afd8ccfca5cfe1fd8ec3..56c8d60bf5b6e46b6bd184010fd9ec51c7e5ea0f 100644 (file)
@@ -3377,7 +3377,7 @@ static void material_panel_tramir(Material *ma)
        
        uiBlockBeginAlign(block);
        uiDefButF(block, NUM, B_MATPRV, "Filter:",
-               X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->filter), 0.0, 1.0, 10, 0, "Amount to blend in the material's diffuse colour in raytraced transparency (simulating absorption)");
+               X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->filter), 0.0, 1.0, 10, 0, "Amount to blend in the material's diffuse color in raytraced transparency (simulating absorption)");
        uiDefButF(block, NUMSLI, B_MATPRV, "Limit: ",
                X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->tx_limit), 0.0, 100.0, 10, 2, "Maximum depth for light to travel through the transparent material before becoming fully filtered (0.0 is disabled)");
        uiDefButF(block, NUMSLI, B_MATPRV, "Falloff: ",
index d67df1e0e972a20e3652fd8321df37d88c70679f..9777415fc0a5006b86c1af45edcfb79487f9468a 100644 (file)
@@ -1021,7 +1021,7 @@ static void drawviewborder(void)
        BIF_ThemeColor(TH_WIRE);
        glRectf(x1, y1, x2, y2);
                
-       /* camera name - draw in highlighted text colour */
+       /* camera name - draw in highlighted text color */
        if (ca && (ca->flag & CAM_SHOWNAME)) {
                BIF_ThemeColor(TH_TEXT_HI);
                glRasterPos2f(x1, y1-15);
index 56db0ea70169774f0dac11af3abc7338cf4aa04b..a68fca3b2949fdae688c827526a388d9f8752d97 100644 (file)
@@ -198,10 +198,10 @@ void convert_to_triface(int direction)
 int removedoublesflag(short flag, short automerge, float limit)                /* return amount */
 {
        /*
-               flag -  Test with vert->flags
-               weld -  Alternative operation, merge unselected into selected.
-                               Used for "Auto Weld" mode. warning.
-               limit - Quick manhattan distance between verts.
+               flag -          Test with vert->flags
+               automerge -     Alternative operation, merge unselected into selected.
+                                       Used for "Auto Weld" mode. warning.
+               limit -         Quick manhattan distance between verts.
        */
        
        EditMesh *em = G.editMesh;
@@ -211,7 +211,6 @@ int removedoublesflag(short flag, short automerge, float limit)             /* return amoun
        EditFace *efa, *nextvl;
        xvertsort *sortblock, *sb, *sb1;
        struct facesort *vlsortblock, *vsb, *vsb1;
-       float dist;
        int a, b, test, amount;
        
        if(multires_test()) return 0;
@@ -253,7 +252,7 @@ int removedoublesflag(short flag, short automerge, float limit)             /* return amoun
                                for(b=a+1; b<amount && (eve->f & 128)==0; b++, sb1++) {
                                        if(sb1->x - sb->x > limit) break;
                                        
-                                       /* when welding, only allow selected-> unselected*/
+                                       /* when automarge, only allow unselected->selected */
                                        v1= sb1->v1;
                                        if( (v1->f & 128)==0 ) {
                                                if ((eve->f & flag)==0 && (v1->f & flag)==1) {
index d9981f58ac264d8cf274aa91cae45fdfd5fd477d..280c69e2719d5fd33d3f40611033ab6a949837ab 100644 (file)
@@ -103,6 +103,8 @@ void add_marker(int frame)
        BIF_undo_push("Add Marker");
 }
 
+
+
 /* remove selected TimeMarkers */
 void remove_marker(void)
 {
@@ -733,6 +735,27 @@ void nextprev_timeline_key(short dir)
        }
 }
 
+/* return the current marker for this frame,
+we can have more then 1 marker per frame, this just returns the first :/ */
+TimeMarker *get_frame_marker(int frame)
+{
+       TimeMarker *marker, *best_marker = NULL;
+       int best_frame = -MAXFRAME*2; 
+       for (marker= G.scene->markers.first; marker; marker= marker->next) {
+               if (marker->frame==frame) {
+                       return marker;
+               }
+               
+               if ( marker->frame > best_frame && marker->frame < frame) {
+                       best_marker = marker;
+                       best_frame = marker->frame;
+               }
+       }
+       
+       return best_marker;
+}
+
+
 void timeline_frame_to_center(void)
 {
        float dtime;
index 0147435965d44c1e1aa228ac3e35206326ae2cac..ad48d3cc91918409f713e11c20dfd073759ab9e0 100644 (file)
@@ -850,7 +850,7 @@ static void setNearestAxis2d(TransInfo *t)
        ival[1]= t->imval[1];
        
        /* no correction needed... just use whichever one is lower */
-       if ( abs(mval[0]-ival[0]) > abs(mval[1]-ival[1]) ) {
+       if ( abs(mval[0]-ival[0]) < abs(mval[1]-ival[1]) ) {
                t->con.mode |= CON_AXIS1;
                sprintf(t->con.text, " along Y axis");
        }