Pull request with discussion here: https://github.com/libharu/libharu/pull/157
Has this been implemented by other distro's? If kitware can support VTK, perhaps they can invest some time in proposing a new release with some of the other pull requests? I think this is a better way forward for the community than having maintainers of different distro's having to add patches to support features. On Fri, Mar 23, 2018 at 8:19 PM, Kyle Edwards <kyle.edwa...@kitware.com> wrote: > Source: libharu > Severity: wishlist > Tags: patch > > Dear Maintainer, > > I am working on an official Kitware-supported Debian/Ubuntu package for > the upcoming VTK 9. We are using a custom shading feature developed > in-house for libharu. We have submitted our changes upstream, but the > project has been abandoned and the patch will most likely never be > accepted. Please backport the included patch so that we can bring VTK 9 > to Debian. Thank you for your support. > > > *** patches/0001-Add-support-for-free-form-triangle-Shading-objects.patch > From 9e8ba2f5453552909e52fde5ec30856004a616d0 Mon Sep 17 00:00:00 2001 > From: "David C. Lonie" <david.lo...@kitware.com> > Date: Wed, 10 May 2017 11:07:28 -0400 > Subject: [PATCH] Add support for free-form triangle Shading objects. > > --- > include/hpdf.h | 24 ++++- > include/hpdf_error.h | 3 + > include/hpdf_objects.h | 2 + > include/hpdf_pages.h | 5 + > include/hpdf_types.h | 14 +++ > src/CMakeLists.txt | 1 + > src/hpdf_page_operator.c | 31 +++++++ > src/hpdf_pages.c | 55 ++++++++++- > src/hpdf_shading.c | 231 ++++++++++++++++++++++++++++++ > +++++++++++++++++ > 9 files changed, 362 insertions(+), 4 deletions(-) > create mode 100644 src/hpdf_shading.c > > diff --git a/include/hpdf.h b/include/hpdf.h > index e369f67..40e3c41 100644 > --- a/include/hpdf.h > +++ b/include/hpdf.h > @@ -77,6 +77,7 @@ typedef HPDF_HANDLE HPDF_Dict; > typedef HPDF_HANDLE HPDF_EmbeddedFile; > typedef HPDF_HANDLE HPDF_OutputIntent; > typedef HPDF_HANDLE HPDF_Xref; > +typedef HPDF_HANDLE HPDF_Shading; > > #else > > @@ -1171,6 +1172,11 @@ HPDF_EXPORT(HPDF_STATUS) > HPDF_Page_SetExtGState (HPDF_Page page, > HPDF_ExtGState ext_gstate); > > +/* sh */ > +HPDF_EXPORT(HPDF_STATUS) > +HPDF_Page_SetShading (HPDF_Page page, > + HPDF_Shading shading); > + > > /*--- Special graphic state operator ------------------------------ > --------*/ > > @@ -1450,7 +1456,23 @@ HPDF_Page_SetCMYKStroke (HPDF_Page page, > > /*--- Shading patterns ------------------------------ > ---------------------*/ > > -/* sh --not implemented yet */ > +/* Notes for docs: > + * - ShadingType must be HPDF_SHADING_FREE_FORM_TRIANGLE_MESH (the only > + * defined option...) > + * - colorSpace must be HPDF_CS_DEVICE_RGB for now. > + */ > +HPDF_EXPORT(HPDF_Shading) > +HPDF_Shading_New (HPDF_Doc pdf, > + HPDF_ShadingType type, > + HPDF_ColorSpace colorSpace, > + HPDF_REAL xMin, HPDF_REAL xMax, > + HPDF_REAL yMin, HPDF_REAL yMax); > + > +HPDF_EXPORT(HPDF_STATUS) > +HPDF_Shading_AddVertexRGB(HPDF_Shading shading, > + HPDF_Shading_FreeFormTriangleMeshEdgeFlag > edgeFlag, > + HPDF_REAL x, HPDF_REAL y, > + HPDF_UINT8 r, HPDF_UINT8 g, HPDF_UINT8 b); > > /*--- In-line images ------------------------------ > -----------------------*/ > > diff --git a/include/hpdf_error.h b/include/hpdf_error.h > index b04e2cd..ef4fa61 100644 > --- a/include/hpdf_error.h > +++ b/include/hpdf_error.h > @@ -145,6 +145,9 @@ extern "C" { > #define HPDF_INVALID_U3D_DATA 0x1083 > #define HPDF_NAME_CANNOT_GET_NAMES 0x1084 > #define HPDF_INVALID_ICC_COMPONENT_NUM 0x1085 > +/* 0x1086 */ > +/* 0x1087 */ > +#define HPDF_INVALID_SHADING_TYPE 0x1088 > > /*---------------------------------------------------------- > -----------------*/ > > diff --git a/include/hpdf_objects.h b/include/hpdf_objects.h > index 525adda..b16de02 100644 > --- a/include/hpdf_objects.h > +++ b/include/hpdf_objects.h > @@ -61,6 +61,7 @@ extern "C" { > #define HPDF_OSUBCLASS_EXT_GSTATE_R 0x0B00 /* read only object */ > #define HPDF_OSUBCLASS_NAMEDICT 0x0C00 > #define HPDF_OSUBCLASS_NAMETREE 0x0D00 > +#define HPDF_OSUBCLASS_SHADING 0x0E00 > > > > @@ -595,6 +596,7 @@ typedef HPDF_Array HPDF_Destination; > typedef HPDF_Dict HPDF_U3D; > typedef HPDF_Dict HPDF_OutputIntent; > typedef HPDF_Dict HPDF_JavaScript; > +typedef HPDF_Dict HPDF_Shading; > > #ifdef __cplusplus > } > diff --git a/include/hpdf_pages.h b/include/hpdf_pages.h > index 44b816c..60b1d84 100644 > --- a/include/hpdf_pages.h > +++ b/include/hpdf_pages.h > @@ -55,6 +55,7 @@ typedef struct _HPDF_PageAttr_Rec { > HPDF_Dict fonts; > HPDF_Dict xobjects; > HPDF_Dict ext_gstates; > + HPDF_Dict shadings; > HPDF_GState gstate; > HPDF_Point str_pos; > HPDF_Point cur_pos; > @@ -101,6 +102,10 @@ const char* > HPDF_Page_GetExtGStateName (HPDF_Page page, > HPDF_ExtGState gstate); > > +const char* > +HPDF_Page_GetShadingName (HPDF_Page page, > + HPDF_Shading shading); > + > > HPDF_Box > HPDF_Page_GetMediaBox (HPDF_Page page); > diff --git a/include/hpdf_types.h b/include/hpdf_types.h > index 8b3e0a8..a2e2157 100644 > --- a/include/hpdf_types.h > +++ b/include/hpdf_types.h > @@ -557,6 +557,20 @@ typedef enum _HPDF_NameDictKey { > HPDF_NAME_EOF > } HPDF_NameDictKey; > > +/*--------------------------------------------------------- > -------------------*/ > + > +typedef enum _HPDF_ShadingType { > + HPDF_SHADING_FREE_FORM_TRIANGLE_MESH = 4 /* TODO the rest */ > +} HPDF_ShadingType; > + > +typedef enum _HPDF_Shading_FreeFormTriangleMeshEdgeFlag { > + HPDF_FREE_FORM_TRI_MESH_EDGEFLAG_NO_CONNECTION = 0, > + HPDF_FREE_FORM_TRI_MESH_EDGEFLAG_BC, > + HPDF_FREE_FORM_TRI_MESH_EDGEFLAG_AC > +} HPDF_Shading_FreeFormTriangleMeshEdgeFlag; > + > +/*--------------------------------------------------------- > -------------------*/ > + > #ifdef __cplusplus > } > #endif /* __cplusplus */ > diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt > index 9d2a604..71c7d10 100644 > --- a/src/CMakeLists.txt > +++ b/src/CMakeLists.txt > @@ -56,6 +56,7 @@ set( > hpdf_page_operator.c > hpdf_pages.c > hpdf_real.c > + hpdf_shading.c > hpdf_streams.c > hpdf_string.c > hpdf_u3d.c > diff --git a/src/hpdf_page_operator.c b/src/hpdf_page_operator.c > index 23f5920..dda1078 100644 > --- a/src/hpdf_page_operator.c > +++ b/src/hpdf_page_operator.c > @@ -312,6 +312,37 @@ HPDF_Page_SetExtGState (HPDF_Page page, > return ret; > } > > +/* sh */ > +HPDF_EXPORT(HPDF_STATUS) > +HPDF_Page_SetShading (HPDF_Page page, > + HPDF_Shading shading) > +{ > + HPDF_STATUS ret = HPDF_Page_CheckState (page, > HPDF_GMODE_PAGE_DESCRIPTION); > + HPDF_PageAttr attr; > + const char *local_name; > + > + HPDF_PTRACE ((" HPDF_Page_SetShading\n")); > + > + if (ret != HPDF_OK) > + return ret; > + > + if (page->mmgr != shading->mmgr) > + return HPDF_RaiseError (page->error, HPDF_INVALID_OBJECT, 0); > + > + attr = (HPDF_PageAttr)page->attr; > + local_name = HPDF_Page_GetShadingName (page, shading); > + > + if (!local_name) > + return HPDF_CheckError (page->error); > + > + if (HPDF_Stream_WriteEscapeName (attr->stream, local_name) != HPDF_OK) > + return HPDF_CheckError (page->error); > + > + if (HPDF_Stream_WriteStr (attr->stream, " sh\012") != HPDF_OK) > + return HPDF_CheckError (page->error); > + > + return ret; > +} > > /*--- Special graphic state operator ------------------------------ > --------*/ > > diff --git a/src/hpdf_pages.c b/src/hpdf_pages.c > index fcc9b5c..c0a7c4f 100644 > --- a/src/hpdf_pages.c > +++ b/src/hpdf_pages.c > @@ -514,7 +514,7 @@ HPDF_Page_GetLocalFontName (HPDF_Page page, > /* search font-object from font-resource */ > key = HPDF_Dict_GetKeyByObj (attr->fonts, font); > if (!key) { > - /* if the font is not resisterd in font-resource, register font to > + /* if the font is not registered in font-resource, register font > to > * font-resource. > */ > char fontName[HPDF_LIMIT_MAX_NAME_LEN + 1]; > @@ -603,7 +603,7 @@ HPDF_Page_GetXObjectName (HPDF_Page page, > /* search xobject-object from xobject-resource */ > key = HPDF_Dict_GetKeyByObj (attr->xobjects, xobj); > if (!key) { > - /* if the xobject is not resisterd in xobject-resource, register > + /* if the xobject is not registered in xobject-resource, register > * xobject to xobject-resource. > */ > char xobj_name[HPDF_LIMIT_MAX_NAME_LEN + 1]; > @@ -654,7 +654,7 @@ HPDF_Page_GetExtGStateName (HPDF_Page page, > /* search ext_gstate-object from ext_gstate-resource */ > key = HPDF_Dict_GetKeyByObj (attr->ext_gstates, state); > if (!key) { > - /* if the ext-gstate is not resisterd in ext-gstate resource, > register > + /* if the ext-gstate is not registered in ext-gstate resource, > register > * to ext-gstate resource. > */ > char ext_gstate_name[HPDF_LIMIT_MAX_NAME_LEN + 1]; > @@ -673,6 +673,55 @@ HPDF_Page_GetExtGStateName (HPDF_Page page, > return key; > } > > +const char* > +HPDF_Page_GetShadingName (HPDF_Page page, > + HPDF_Shading shading) > +{ > + HPDF_PageAttr attr = (HPDF_PageAttr )page->attr; > + const char *key; > + > + HPDF_PTRACE((" HPDF_Page_GetShadingName\n")); > + > + if (!attr->shadings) { > + HPDF_Dict resources; > + HPDF_Dict shadings; > + > + resources = HPDF_Page_GetInheritableItem (page, "Resources", > + HPDF_OCLASS_DICT); > + if (!resources) > + return NULL; > + > + shadings = HPDF_Dict_New (page->mmgr); > + if (!shadings) > + return NULL; > + > + if (HPDF_Dict_Add (resources, "Shading", shadings) != HPDF_OK) > + return NULL; > + > + attr->shadings = shadings; > + } > + > + /* search shading-object from shading-resource */ > + key = HPDF_Dict_GetKeyByObj (attr->shadings, shading); > + if (!key) { > + /* if the shading is not registered in shadings resource, register > + * to shadings resource. > + */ > + char shading_str[HPDF_LIMIT_MAX_NAME_LEN + 1]; > + char *ptr; > + char *end_ptr = shading_str + HPDF_LIMIT_MAX_NAME_LEN; > + > + ptr = (char *)HPDF_StrCpy (shading_str, "Sh", end_ptr); > + HPDF_IToA (ptr, attr->shadings->list->count, end_ptr); > + > + if (HPDF_Dict_Add (attr->shadings, shading_str, shading) != > HPDF_OK) > + return NULL; > + > + key = HPDF_Dict_GetKeyByObj (attr->shadings, shading); > + } > + > + return key; > +} > > static HPDF_STATUS > AddAnnotation (HPDF_Page page, > diff --git a/src/hpdf_shading.c b/src/hpdf_shading.c > new file mode 100644 > index 0000000..53204c0 > --- /dev/null > +++ b/src/hpdf_shading.c > @@ -0,0 +1,231 @@ > +/* > + * << Haru Free PDF Library >> -- hpdf_shading.c > + * > + * URL: http://libharu.org > + * > + * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_ka...@est.hi-ho.ne.jp> > + * Copyright (c) 2007-2009 Antony Dovgal <t...@daylessday.org> > + * Copyright (c) 2017 Kitware <kitw...@kitware.com> > + * > + * Permission to use, copy, modify, distribute and sell this software > + * and its documentation for any purpose is hereby granted without fee, > + * provided that the above copyright notice appear in all copies and > + * that both that copyright notice and this permission notice appear > + * in supporting documentation. > + * It is provided "as is" without express or implied warranty. > + * > + */ > + > +#include "hpdf.h" > +#include "hpdf_utils.h" > + > +#include "assert.h" > + > +typedef struct _RGBVertex > +{ > + HPDF_UINT8 EdgeFlag; > + HPDF_UINT32 X; > + HPDF_UINT32 Y; > + HPDF_UINT8 RGB[3]; > +} RGBVertex; > + > +static const char *COL_CMYK = "DeviceCMYK"; > +static const char *COL_RGB = "DeviceRGB"; > +static const char *COL_GRAY = "DeviceGray"; > + > +/* bbox is filled with xMin, xMax, yMin, yMax */ > +static HPDF_BOOL _GetDecodeArrayVertexValues(HPDF_Shading shading, > + HPDF_REAL *bbox) > +{ > + HPDF_Array decodeArray; > + HPDF_Real r; > + int i; > + > + if (!shading) { > + return HPDF_FALSE; > + } > + > + decodeArray = (HPDF_Array)(HPDF_Dict_GetItem(shading, "Decode", > + HPDF_OCLASS_ARRAY)); > + if (!decodeArray) { > + return HPDF_FALSE; > + } > + > + for (i = 0; i < 4; ++i) > + { > + r = HPDF_Array_GetItem(decodeArray, i, HPDF_OCLASS_REAL); > + if (!r) { > + return HPDF_FALSE; > + } > + > + bbox[i] = r->value; > + } > + > + return HPDF_TRUE; > +} > + > +static void UINT32Swap (HPDF_UINT32 *value) > +{ > + HPDF_BYTE b[4]; > + > + HPDF_MemCpy (b, (HPDF_BYTE *)value, 4); > + *value = (HPDF_UINT32)((HPDF_UINT32)b[0] << 24 | > + (HPDF_UINT32)b[1] << 16 | > + (HPDF_UINT32)b[2] << 8 | > + (HPDF_UINT32)b[3]); > +} > + > +/* Encode a position coordinate for writing */ > +static HPDF_UINT32 _EncodeValue(HPDF_REAL x, HPDF_REAL xMin, HPDF_REAL > xMax) > +{ > + HPDF_DOUBLE norm = (x - xMin) / (xMax - xMin); > + HPDF_DOUBLE max = (HPDF_DOUBLE)(0xFFFFFFFF); > + HPDF_UINT32 enc = (HPDF_UINT32)(norm * max); > + UINT32Swap(&enc); > + return enc; > +} > + > +HPDF_EXPORT(HPDF_Shading) > +HPDF_Shading_New (HPDF_Doc pdf, > + HPDF_ShadingType type, > + HPDF_ColorSpace colorSpace, > + HPDF_REAL xMin, HPDF_REAL xMax, > + HPDF_REAL yMin, HPDF_REAL yMax) > +{ > + HPDF_Shading shading; > + HPDF_Array decodeArray; > + HPDF_STATUS ret = HPDF_OK; > + int i; > + > + HPDF_PTRACE((" HPDF_Shading_New\n")); > + > + if (!HPDF_HasDoc(pdf)) { > + return NULL; > + } > + > + /* Validate shading type: */ > + switch (type) > + { > + case HPDF_SHADING_FREE_FORM_TRIANGLE_MESH: > + break; > + > + default: > + HPDF_SetError (pdf->mmgr->error, HPDF_INVALID_SHADING_TYPE, 0); > + return NULL; > + } > + > + decodeArray = HPDF_Array_New(pdf->mmgr); > + if (!decodeArray) { > + return NULL; > + } > + > + /* X-range */ > + ret += HPDF_Array_AddReal(decodeArray, xMin); > + ret += HPDF_Array_AddReal(decodeArray, xMax); > + > + /* Y-range */ > + ret += HPDF_Array_AddReal(decodeArray, yMin); > + ret += HPDF_Array_AddReal(decodeArray, yMax); > + > + const char *colName = NULL; > + switch (colorSpace) { > + case HPDF_CS_DEVICE_RGB: > + colName = COL_RGB; > + for (i = 0; i < 3; ++i) { > + ret += HPDF_Array_AddReal(decodeArray, 0.0); > + ret += HPDF_Array_AddReal(decodeArray, 1.0); > + } > + break; > + > + default: > + HPDF_SetError(pdf->mmgr->error, HPDF_INVALID_COLOR_SPACE, 0); > + return NULL; > + } > + > + if (ret != HPDF_OK) { > + return NULL; > + } > + > + shading = HPDF_DictStream_New(pdf->mmgr, pdf->xref); > + if (!shading) { > + return NULL; > + } > + > + shading->header.obj_class |= HPDF_OSUBCLASS_SHADING; > + ret += HPDF_Dict_AddNumber(shading, "ShadingType", type); > + ret += HPDF_Dict_AddName(shading, "ColorSpace", colName); > + > + switch (type) > + { > + case HPDF_SHADING_FREE_FORM_TRIANGLE_MESH: > + ret += HPDF_Dict_AddNumber(shading, "BitsPerCoordinate", 32); > + ret += HPDF_Dict_AddNumber(shading, "BitsPerComponent", 8); > + ret += HPDF_Dict_AddNumber(shading, "BitsPerFlag", 8); > + ret += HPDF_Dict_Add(shading, "Decode", decodeArray); > + break; > + > + default: > + HPDF_SetError (pdf->mmgr->error, HPDF_INVALID_SHADING_TYPE, 0); > + return NULL; > + } > + > + if (ret != HPDF_OK) { > + return NULL; > + } > + > + return shading; > +} > + > +HPDF_EXPORT(HPDF_STATUS) > +HPDF_Shading_AddVertexRGB(HPDF_Shading shading, > + HPDF_Shading_FreeFormTriangleMeshEdgeFlag > edgeFlag, > + HPDF_REAL x, HPDF_REAL y, > + HPDF_UINT8 r, HPDF_UINT8 g, HPDF_UINT8 b) > +{ > + HPDF_STATUS ret = HPDF_OK; > + RGBVertex vert; > + float bbox[4]; > + > + HPDF_PTRACE((" HPDF_Shading_AddVertexRGB\n")); > + > + if (!shading) { > + return HPDF_INVALID_OBJECT; > + } > + > + if (_GetDecodeArrayVertexValues(shading, bbox) != HPDF_TRUE) { > + return HPDF_SetError(shading->error, HPDF_INVALID_OBJECT, 0); > + } > + > + vert.EdgeFlag = (HPDF_UINT8)edgeFlag; > + vert.X = _EncodeValue(x, bbox[0], bbox[1]); > + vert.Y = _EncodeValue(y, bbox[2], bbox[3]); > + vert.RGB[0] = r; > + vert.RGB[1] = g; > + vert.RGB[2] = b; > + > + ret = HPDF_Stream_Write(shading->stream, > + (HPDF_BYTE*)(&vert.EdgeFlag), > sizeof(vert.EdgeFlag)); > + if (ret != HPDF_OK) > + { > + return ret; > + } > + > + ret = HPDF_Stream_Write(shading->stream, > + (HPDF_BYTE*)(&vert.X), sizeof(vert.X)); > + if (ret != HPDF_OK) > + { > + return ret; > + } > + > + ret = HPDF_Stream_Write(shading->stream, > + (HPDF_BYTE*)(&vert.Y), sizeof(vert.Y)); > + if (ret != HPDF_OK) > + { > + return ret; > + } > + > + ret = HPDF_Stream_Write(shading->stream, > + (HPDF_BYTE*)(&vert.RGB), sizeof(vert.RGB)); > + > + return ret; > +} > -- > 2.16.2 > > > > -- System Information: > Debian Release: buster/sid > APT prefers unstable > APT policy: (500, 'unstable') > Architecture: amd64 (x86_64) > > Kernel: Linux 4.15.0-1-amd64 (SMP w/4 CPU cores) > Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), > LANGUAGE=en_US.UTF-8 (charmap=UTF-8) > Shell: /bin/sh linked to /bin/dash > Init: systemd (via /run/systemd/system) > LSM: AppArmor: enabled >