[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2-demos] master 355c0da 19/22: PNG writing routines using GDI+.,
Werner Lemberg <=