freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2-demos] master 355c0da 19/22: PNG writing routines using GDI+.


From: Werner Lemberg
Subject: [freetype2-demos] master 355c0da 19/22: PNG writing routines using GDI+.
Date: Fri, 5 Mar 2021 11:18:41 -0500 (EST)

branch: master
commit 355c0da184fcf1e53f29ea5e74b7b0d459517f7f
Author: Alexei Podtelezhnikov <apodtele@gmail.com>
Commit: Alexei Podtelezhnikov <apodtele@gmail.com>

    PNG writing routines using GDI+.
    
    * src/ftpngout.c (FTDemo_Display_Print) [_WIN32]: Implement it.
---
 ChangeLog      |   8 +-
 src/ftpngout.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 234 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 9978374..d29fceb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,10 @@
-2021-02-18  Alexei Podtelezhnikov  <apodtele@gmail.com>
+2021-02-24  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+       PNG writing routines using GDI+.
+
+       * src/ftpngout.c (FTDemo_Display_Print) [_WIN32]: Implement it.
+
+2021-02-23  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
        Split out PNG writing routines.
 
diff --git a/src/ftpngout.c b/src/ftpngout.c
index ee79f59..137a186 100644
--- a/src/ftpngout.c
+++ b/src/ftpngout.c
@@ -142,6 +142,233 @@
     return code;
   }
 
+#elif defined( _WIN32 )
+
+#define WIN32_LEAN_AND_MEAN
+#include<windows.h>
+
+#pragma comment (lib,"Gdiplus.lib")
+
+ /* Barebone definitions and opaque types to avoid GDI+ (C++) headers */
+
+#define WINGDIPAPI  WINAPI
+#define GDIPCONST  const
+
+  typedef enum Status {
+    Ok,
+    GenericError,
+    InvalidParameter,
+    OutOfMemory,
+    ObjectBusy,
+    InsufficientBuffer,
+    NotImplemented,
+    Win32Error,
+    WrongState,
+    Aborted,
+    FileNotFound,
+    ValueOverflow,
+    AccessDenied,
+    UnknownImageFormat,
+    FontFamilyNotFound,
+    FontStyleNotFound,
+    NotTrueTypeFont,
+    UnsupportedGdiplusVersion,
+    GdiplusNotInitialized,
+    PropertyNotFound,
+    PropertyNotSupported,
+    ProfileNotFound
+  }  GpStatus;
+
+  typedef VOID (WINGDIPAPI *DebugEventProc)(VOID);  /* unused, NULL */
+
+  typedef struct GdiplusStartupInput {
+    UINT32 GdiplusVersion;
+    DebugEventProc DebugEventCallback;
+    BOOL SuppressBackgroundThread;
+    BOOL SuppressExternalCodecs;
+  }  GdiplusStartupInput;
+
+  typedef VOID GdiplusStartupOutput;  /* unused, NULL */
+
+  GpStatus WINAPI GdiplusStartup(
+    ULONG_PTR *token,
+    GDIPCONST GdiplusStartupInput *input,
+    GdiplusStartupOutput *output
+  );
+
+  VOID WINAPI GdiplusShutdown( ULONG_PTR token);
+
+  typedef enum PixelFormat {
+    PixelFormatUndefined = 0x00000000,
+    PixelFormat1bppIndexed = 0x00030101,
+    PixelFormat4bppIndexed = 0x00030402,
+    PixelFormat8bppIndexed = 0x00030803,
+    PixelFormat16bppGrayScale = 0x00101004,
+    PixelFormat16bppRGB555 = 0x00021005,
+    PixelFormat16bppRGB565 = 0x00021006,
+    PixelFormat16bppARGB1555 = 0x00061007,
+    PixelFormat24bppRGB = 0x00021808,
+    PixelFormat32bppRGB = 0x00022009,
+    PixelFormat32bppARGB = 0x0026200A,
+    PixelFormat32bppPARGB = 0x000E200B,
+    PixelFormat48bppRGB = 0x0010300C,
+    PixelFormat64bppARGB = 0x0034400D,
+    PixelFormat64bppPARGB = 0x001A400E
+  }  PixelFormat;
+
+  typedef VOID  GpBitmap;  /* opaque */
+
+  GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(
+    INT width,
+    INT height,
+    INT stride,
+    PixelFormat format,
+    BYTE* scan0,
+    GpBitmap** bitmap
+  );
+
+  typedef VOID  GpImage;  /* opaque */
+
+  typedef DWORD  ARGB;
+
+  enum PaletteFlags {
+    PaletteFlagsHasAlpha = 1,
+    PaletteFlagsGrayScale = 2,
+    PaletteFlagsHalftone = 4
+  };
+
+  typedef struct ColorPalette {
+    UINT Flags;
+    UINT Count;
+    ARGB Entries[256];
+  }  ColorPalette;
+
+  GpStatus WINGDIPAPI GdipSetImagePalette(
+    GpImage *image,
+    GDIPCONST ColorPalette *palette
+  );
+
+  typedef ULONG  PROPID;
+
+#define PropertyTagTypeASCII  2
+#define PropertyTagTypeRational  5
+#define PropertyTagSoftwareUsed  0x0131
+#define PropertyTagGamma  0x0301
+
+  typedef struct PropertyItem {
+    PROPID id;
+    ULONG length;
+    WORD type;
+    VOID *value;
+  }  PropertyItem;
+
+  GpStatus WINGDIPAPI GdipSetPropertyItem(
+    GpImage *image,
+    GDIPCONST PropertyItem* item
+  );
+
+  typedef GUID  CLSID;
+
+  typedef VOID  EncoderParameters;
+
+  GpStatus WINGDIPAPI GdipSaveImageToFile(
+    GpImage *image,
+    GDIPCONST WCHAR* filename,
+    GDIPCONST CLSID* clsidEncoder,
+    GDIPCONST EncoderParameters* encoderParams
+  );
+
+  GpStatus WINGDIPAPI GdipFree(void* ptr);
+
+
+  int
+  FTDemo_Display_Print( FTDemo_Display*  display,
+                        const char*      filename,
+                        FT_String*       ver_str )
+  {
+    grBitmap*  bit = display->bitmap;
+
+    WCHAR         wfilename[20];
+    PixelFormat   format;
+    ColorPalette  palette;
+    GpStatus      ret = Ok;
+
+    GdiplusStartupInput  gdiplusStartupInput = { 1, NULL, FALSE, FALSE };
+    ULONG_PTR            gdiplusToken = 0;
+    GpBitmap*            bitmap = NULL;
+    GDIPCONST CLSID      GpPngEncoder = { 0x557cf406, 0x1a04, 0x11d3,
+                           { 0x9a,0x73,0x00,0x00,0xf8,0x1e,0xf3,0x2e } };
+
+    ULONG         gg[2] =    { display->gamma * 0x10000, 0x10000 };
+    PropertyItem  gamma =    { PropertyTagGamma, 2 * sizeof(ULONG),
+                               PropertyTagTypeRational, gg };
+    PropertyItem  software = { PropertyTagSoftwareUsed, strlen(ver_str) + 1,
+                               PropertyTagTypeASCII, ver_str };
+
+
+    /* Set format */
+    switch ( bit->mode )
+    {
+    case gr_pixel_mode_gray:
+      {
+        ARGB   color;
+        ARGB*  entry = palette.Entries;
+
+        palette.Flags = PaletteFlagsGrayScale;
+        palette.Count = 256;
+
+        format = PixelFormat8bppIndexed;
+        for ( color = 0xFF000000; color >= 0xFF000000 ; color += 0x00010101 )
+          *entry++ = color;
+      }
+      break;
+    case gr_pixel_mode_rgb555:
+      format = PixelFormat16bppRGB555;
+      break;
+    case gr_pixel_mode_rgb565:
+      format = PixelFormat16bppRGB565;
+      break;
+    case gr_pixel_mode_rgb24:  /* XXX: wrong endianness */
+      format = PixelFormat24bppRGB;
+      break;
+    case gr_pixel_mode_rgb32:
+      format = PixelFormat32bppRGB;
+      break;
+    default:
+      fprintf( stderr, "Unsupported color type.\n" );
+      ret = UnknownImageFormat;
+      goto Exit;
+    }
+
+    if ( mbstowcs( wfilename, filename, 20 ) != strlen(filename) )
+       ret = InsufficientBuffer;
+
+    if ( !ret )
+      ret = GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL );
+
+    if ( !ret )
+      ret = GdipCreateBitmapFromScan0( bit->width, bit->rows, bit->pitch,
+                                       format, bit->buffer, &bitmap);
+
+    if ( !ret && format == PixelFormat8bppIndexed )
+      ret = GdipSetImagePalette( bitmap, &palette );
+
+    if ( !ret )
+      ret = GdipSetPropertyItem( bitmap, &gamma );
+
+    if ( !ret )
+      ret = GdipSetPropertyItem( bitmap, &software );
+
+    if ( !ret )
+      ret = GdipSaveImageToFile( bitmap, wfilename, &GpPngEncoder, NULL );
+
+    GdipFree( bitmap );
+    GdiplusShutdown( gdiplusToken );
+
+  Exit:
+    return ret;
+  }
+
 #else
 
   int



reply via email to

[Prev in Thread] Current Thread [Next in Thread]