| Name |
| |
| NV_path_rendering |
| |
| Name Strings |
| |
| GL_NV_path_rendering |
| |
| Contact |
| |
| Mark Kilgard, NVIDIA (mjk 'at' nvidia.com) |
| |
| Contributors |
| |
| Roger Allen, NVIDIA |
| Jeff Bolz, NVIDIA |
| Chris Dalton, NVIDIA |
| Pierre-Loup Griffais, NVIDIA |
| Chris Hebert, Samsung |
| Scott Nations, NVIDIA |
| David Chait, NVIDIA |
| Daniel Koch, NVIDIA |
| Bas Schouten, Mozilla |
| Sandeep Shinde, NVIDIA |
| |
| Status |
| |
| Released in NVIDIA Driver Release 275.33 (June 2011). |
| |
| Substantially optimized in NVIDIA Driver Release 301.42 (May 2012). |
| |
| Further optimized in NVIDIA Driver Release 314.xx (February 2013). |
| |
| Version 1.3 functionality shipping in NVIDIA Driver Release 337.88 |
| and on (May, 27 2014). |
| |
| Version |
| |
| Last Modified Date: September 9, 2014 |
| Version: 35 |
| |
| Number |
| |
| OpenGL Extension #410 |
| OpenGL ES Extension #199 |
| |
| Dependencies |
| |
| This extension is written against the OpenGL 3.2 Specification with |
| Compatibility Profile but can apply to OpenGL 1.1 and up. |
| |
| When used with a Core profile or OpenGL ES context, certain |
| functionality is unavailable (see "Dependencies on Core Profile and |
| OpenGL ES" section). |
| |
| This extension depends on ARB_program_interface_query. |
| |
| EXT_direct_state_access commands are used in specifying portions |
| of this extension but EXT_direct_state_access is not required to |
| implement this extension as long as the functionality implemented |
| is equivalent to the EXT_direct_state_access commands. |
| |
| EXT_separate_shader_objects is recommended. |
| |
| ARB_program_interface_query is recommended. |
| |
| Overview |
| |
| Conventional OpenGL supports rendering images (pixel rectangles and |
| bitmaps) and simple geometric primitives (points, lines, polygons). |
| |
| This extension adds a new rendering paradigm, known as path rendering, |
| for rendering filled and stroked paths. Path rendering is not novel |
| but rather a standard part of most resolution-independent 2D rendering |
| systems such as Flash, PDF, Silverlight, SVG, Java 2D, Office |
| drawings, TrueType fonts, PostScript and its fonts, Quartz 2D, XML |
| Paper Specification (XPS), and OpenVG. What is novel is the ability |
| to mix path rendering with arbitrary OpenGL 3D rendering and imaging. |
| |
| With this extension, path rendering becomes a first-class rendering |
| mode within the OpenGL graphics system that can be arbitrarily mixed |
| with existing OpenGL rendering and can take advantage of OpenGL's |
| existing mechanisms for texturing, programmability, and per-fragment |
| operations. |
| |
| Unlike geometric primitive rendering, paths are specified on a 2D |
| (non-projective) plane rather than in 3D (projective) space. |
| Even though the path is defined in a 2D plane, every path can |
| be transformed into 3D clip space allowing for 3D view frustum & |
| user-defined clipping, depth offset, and depth testing in the same |
| manner as geometric primitive rendering. |
| |
| Both geometric primitive rendering and path rendering support |
| rasterization of edges defined by line segments; however, path |
| rendering also allows path segments to be specified by Bezier (cubic |
| or quadratic) curves or partial elliptical arcs. This allows path |
| rendering to define truly curved primitive boundaries unlike the |
| straight edges of line and polygon primitives. Whereas geometric |
| primitive rendering requires convex polygons for well-defined |
| rendering results, path rendering allows (and encourages!) concave |
| and curved outlines to be specified. These paths are even allowed |
| to self-intersect. |
| |
| When filling closed paths, the winding of paths (counterclockwise |
| or clockwise) determines whether pixels are inside or outside of |
| the path. |
| |
| Paths can also be stroked whereby, conceptually, a fixed-width "brush" |
| is pulled along the path such that the brush remains orthogonal to |
| the gradient of each path segment. Samples within the sweep of this |
| brush are considered inside the stroke of the path. |
| |
| This extension supports path rendering through a sequence of three |
| operations: |
| |
| 1. Path specification is the process of creating and updating |
| a path object consisting of a set of path commands and a |
| corresponding set of 2D vertices. |
| |
| Path commands can be specified explicitly from path command |
| and coordinate data, parsed from a string based on standard |
| grammars for representing paths, or specified by a particular |
| glyph of standard font representations. Also new paths can |
| be specified by weighting one or more existing paths so long |
| as all the weighted paths have consistent command sequences. |
| |
| Each path object contains zero or more subpaths specified |
| by a sequence of line segments, partial elliptical arcs, |
| and (cubic or quadratic) Bezier curve segments. Each path |
| may contain multiple subpaths that can be closed (forming |
| a contour) or open. |
| |
| 2. Path stenciling is the process of updating the stencil buffer |
| based on a path's coverage transformed into window space. |
| |
| Path stenciling can determine either the filled or stroked |
| coverage of a path. |
| |
| The details of path stenciling are explained within the core |
| of the specification. |
| |
| Stenciling a stroked path supports all the standard |
| embellishments for path stroking such as end caps, join |
| styles, miter limits, dashing, and dash caps. These stroking |
| properties specified are parameters of path objects. |
| |
| 3. Path covering is the process of emitting simple (convex & |
| planar) geometry that (conservatively) "covers" the path's |
| sample coverage in the stencil buffer. During path covering, |
| stencil testing can be configured to discard fragments not |
| within the actual coverage of the path as determined by |
| prior path stenciling. |
| |
| Path covering can cover either the filled or stroked coverage |
| of a path. |
| |
| The details of path covering are explained within the core |
| of the specification. |
| |
| To render a path object into the color buffer, an application specifies |
| a path object and then uses a two-step rendering process. First, the |
| path object is stenciled whereby the path object's stroked or filled |
| coverage is rasterized into the stencil buffer. Second, the path object |
| is covered whereby conservative bounding geometry for the path is |
| transformed and rasterized with stencil testing configured to test against |
| the coverage information written to the stencil buffer in the first step |
| so that only fragments covered by the path are written during this second |
| step. Also during this second step written pixels typically have |
| their stencil value reset (so there's no need for clearing the |
| stencil buffer between rendering each path). |
| |
| Here is an example of specifying and then rendering a five-point |
| star and a heart as a path using Scalable Vector Graphics (SVG) |
| path description syntax: |
| |
| GLuint pathObj = 42; |
| const char *svgPathString = |
| // star |
| "M100,180 L40,10 L190,120 L10,120 L160,10 z" |
| // heart |
| "M300 300 C 100 400,100 200,300 100,500 200,500 400,300 300Z"; |
| glPathStringNV(pathObj, GL_PATH_FORMAT_SVG_NV, |
| (GLsizei)strlen(svgPathString), svgPathString); |
| |
| Alternatively applications oriented around the PostScript imaging |
| model can use the PostScript user path syntax instead: |
| |
| const char *psPathString = |
| // star |
| "100 180 moveto" |
| " 40 10 lineto 190 120 lineto 10 120 lineto 160 10 lineto closepath" |
| // heart |
| " 300 300 moveto" |
| " 100 400 100 200 300 100 curveto" |
| " 500 200 500 400 300 300 curveto closepath"; |
| glPathStringNV(pathObj, GL_PATH_FORMAT_PS_NV, |
| (GLsizei)strlen(psPathString), psPathString); |
| |
| The PostScript path syntax also supports compact and precise binary |
| encoding and includes PostScript-style circular arcs. |
| |
| Or the path's command and coordinates can be specified explicitly: |
| |
| static const GLubyte pathCommands[10] = |
| { GL_MOVE_TO_NV, GL_LINE_TO_NV, GL_LINE_TO_NV, GL_LINE_TO_NV, |
| GL_LINE_TO_NV, GL_CLOSE_PATH_NV, |
| 'M', 'C', 'C', 'Z' }; // character aliases |
| static const GLshort pathCoords[12][2] = |
| { {100, 180}, {40, 10}, {190, 120}, {10, 120}, {160, 10}, |
| {300,300}, {100,400}, {100,200}, {300,100}, |
| {500,200}, {500,400}, {300,300} }; |
| glPathCommandsNV(pathObj, 10, pathCommands, 24, GL_SHORT, pathCoords); |
| |
| Before rendering to a window with a stencil buffer, clear the stencil |
| buffer to zero and the color buffer to black: |
| |
| glClearStencil(0); |
| glClearColor(0,0,0,0); |
| glStencilMask(~0); |
| glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| |
| Use an orthographic path-to-clip-space transform to map the |
| [0..500]x[0..400] range of the star's path coordinates to the [-1..1] |
| clip space cube: |
| |
| glMatrixLoadIdentityEXT(GL_PROJECTION); |
| glMatrixLoadIdentityEXT(GL_MODELVIEW); |
| glMatrixOrthoEXT(GL_MODELVIEW, 0, 500, 0, 400, -1, 1); |
| |
| Stencil the path: |
| |
| glStencilFillPathNV(pathObj, GL_COUNT_UP_NV, 0x1F); |
| |
| The 0x1F mask means the counting uses modulo-32 arithmetic. In |
| principle the star's path is simple enough (having a maximum winding |
| number of 2) that modulo-4 arithmetic would be sufficient so the mask |
| could be 0x3. Or a mask of all 1's (~0) could be used to count with |
| all available stencil bits. |
| |
| Now that the coverage of the star and the heart have been rasterized |
| into the stencil buffer, cover the path with a non-zero fill style |
| (indicated by the GL_NOTEQUAL stencil function with a zero reference |
| value): |
| |
| glEnable(GL_STENCIL_TEST); |
| glStencilFunc(GL_NOTEQUAL, 0, 0x1F); |
| glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); |
| glColor3f(1,1,0); // yellow |
| glCoverFillPathNV(pathObj, GL_BOUNDING_BOX_NV); |
| |
| The result is a yellow star (with a filled center) to the left of |
| a yellow heart. |
| |
| The GL_ZERO stencil operation ensures that any covered samples |
| (meaning those with non-zero stencil values) are zero'ed when |
| the path cover is rasterized. This allows subsequent paths to be |
| rendered without clearing the stencil buffer again. |
| |
| A similar two-step rendering process can draw a white outline |
| over the star and heart. |
| |
| Before rendering, configure the path object with desirable path |
| parameters for stroking. Specify a wider 6.5-unit stroke and |
| the round join style: |
| |
| glPathParameteriNV(pathObj, GL_PATH_JOIN_STYLE_NV, GL_ROUND_NV); |
| glPathParameterfNV(pathObj, GL_PATH_STROKE_WIDTH_NV, 6.5); |
| |
| Now stencil the path's stroked coverage into the stencil buffer, |
| setting the stencil to 0x1 for all stencil samples within the |
| transformed path. |
| |
| glStencilStrokePathNV(pathObj, 0x1, ~0); |
| |
| Cover the path's stroked coverage (with a hull this time instead |
| of a bounding box; the choice doesn't really matter here) while |
| stencil testing that writes white to the color buffer and again |
| zero the stencil buffer. |
| |
| glColor3f(1,1,1); // white |
| glCoverStrokePathNV(pathObj, GL_CONVEX_HULL_NV); |
| |
| In this example, constant color shading is used but the application |
| can specify their own arbitrary shading and/or blending operations, |
| whether with Cg compiled to fragment program assembly, GLSL, or |
| fixed-function fragment processing. |
| |
| More complex path rendering is possible such as clipping one path to |
| another arbitrary path. This is because stencil testing (as well |
| as depth testing, depth bound test, clip planes, and scissoring) |
| can restrict path stenciling. |
| |
| Now let's render the word "OpenGL" atop the star and heart. |
| |
| First create a sequence of path objects for the glyphs for the |
| characters in "OpenGL": |
| |
| GLuint glyphBase = glGenPathsNV(6); |
| const unsigned char *word = "OpenGL"; |
| const GLsizei wordLen = (GLsizei)strlen(word); |
| const GLfloat emScale = 2048; // match TrueType convention |
| GLuint templatePathObject = ~0; // Non-existent path object |
| glPathGlyphsNV(glyphBase, |
| GL_SYSTEM_FONT_NAME_NV, "Helvetica", GL_BOLD_BIT_NV, |
| wordLen, GL_UNSIGNED_BYTE, word, |
| GL_SKIP_MISSING_GLYPH_NV, ~0, emScale); |
| glPathGlyphsNV(glyphBase, |
| GL_SYSTEM_FONT_NAME_NV, "Arial", GL_BOLD_BIT_NV, |
| wordLen, GL_UNSIGNED_BYTE, word, |
| GL_SKIP_MISSING_GLYPH_NV, ~0, emScale); |
| glPathGlyphsNV(glyphBase, |
| GL_STANDARD_FONT_NAME_NV, "Sans", GL_BOLD_BIT_NV, |
| wordLen, GL_UNSIGNED_BYTE, word, |
| GL_USE_MISSING_GLYPH_NV, ~0, emScale); |
| |
| Glyphs are loaded for three different fonts in priority order: |
| Helvetica first, then Arial, and if neither of those loads, use the |
| standard sans-serif font. If a prior glPathGlyphsNV is successful |
| and specifies the path object range, the subsequent glPathGlyphsNV |
| commands silently avoid re-specifying the already existent path |
| objects. |
| |
| Now query the (kerned) separations for the word "OpenGL" and build |
| a set of horizontal translations advancing each successive glyph by |
| its kerning distance with the following glyph. |
| |
| GLfloat xtranslate[6+1]; // wordLen+1 |
| glGetPathSpacingNV(GL_ACCUM_ADJACENT_PAIRS_NV, |
| wordLen+1, GL_UNSIGNED_BYTE, |
| "\000\001\002\003\004\005\005", // repeat last letter twice |
| glyphBase, |
| 1.0f, 1.0f, |
| GL_TRANSLATE_X_NV, |
| xtranslate); |
| |
| Next determine the font-wide vertical minimum and maximum for the |
| font face by querying the per-font metrics of any one of the glyphs |
| from the font face. |
| |
| GLfloat yMinMax[2]; |
| glGetPathMetricRangeNV(GL_FONT_Y_MIN_BOUNDS_BIT_NV|GL_FONT_Y_MAX_BOUNDS_BIT_NV, |
| glyphBase, /*count*/1, |
| 2*sizeof(GLfloat), |
| yMinMax); |
| |
| Use an orthographic path-to-clip-space transform to map the |
| word's bounds to the [-1..1] clip space cube: |
| |
| glMatrixLoadIdentityEXT(GL_PROJECTION); |
| glMatrixOrthoEXT(GL_MODELVIEW, |
| 0, xtranslate[6], yMinMax[0], yMinMax[1], |
| -1, 1); |
| |
| Stencil the filled paths of the sequence of glyphs for "OpenGL", |
| each transformed by the appropriate 2D translations for spacing. |
| |
| glStencilFillPathInstancedNV(6, GL_UNSIGNED_BYTE, |
| "\000\001\002\003\004\005", |
| glyphBase, |
| GL_PATH_FILL_MODE_NV, 0xFF, |
| GL_TRANSLATE_X_NV, xtranslate); |
| |
| Cover the bounding box union of the glyphs with 50% gray. |
| |
| glEnable(GL_STENCIL_TEST); |
| glStencilFunc(GL_NOTEQUAL, 0, 0xFF); |
| glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); |
| glColor3f(0.5,0.5,0.5); // 50% gray |
| glCoverFillPathInstancedNV(6, GL_UNSIGNED_BYTE, |
| "\000\001\002\003\004\005", |
| glyphBase, |
| GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV, |
| GL_TRANSLATE_X_NV, xtranslate); |
| |
| Voila, the word "OpenGL" in gray is now stenciled into the framebuffer. |
| |
| Instead of solid 50% gray, the cover operation can apply a linear |
| gradient that changes from green (RGB=0,1,0) at the top of the word |
| "OpenGL" to blue (RGB=0,0,1) at the bottom of "OpenGL": |
| |
| GLfloat rgbGen[3][3] = { |
| 0, 0, 0, // red = constant zero |
| 0, 1, 0, // green = varies with y from bottom (0) to top (1) |
| 0, -1, 1 // blue = varies with y from bottom (1) to top (0) |
| }; |
| glPathColorGenNV(GL_PRIMARY_COLOR, GL_PATH_OBJECT_BOUNDING_BOX_NV, |
| GL_RGB, &rgbGen[0][0]); |
| |
| Instead of loading just the glyphs for the characters in "OpenGL", |
| the entire character set could be loaded. This allows the characters |
| of the string to be mapped (offset by the glyphBase) to path object names. |
| A range of glyphs can be loaded like this: |
| |
| const int numChars = 256; // ISO/IEC 8859-1 8-bit character range |
| GLuint glyphBase = glGenPathsNV(numChars); |
| glPathGlyphRangeNV(glyphBase, |
| GL_SYSTEM_FONT_NAME_NV, "Helvetica", GL_BOLD_BIT_NV, |
| 0, numChars, |
| GL_SKIP_MISSING_GLYPH_NV, ~0, emScale); |
| glPathGlyphRangeNV(glyphBase, |
| GL_SYSTEM_FONT_NAME_NV, "Arial", GL_BOLD_BIT_NV, |
| 0, numChars, |
| GL_SKIP_MISSING_GLYPH_NV, ~0, emScale); |
| glPathGlyphRangeNV(glyphBase, |
| GL_STANDARD_FONT_NAME_NV, "Sans", GL_BOLD_BIT_NV, |
| 0, numChars, |
| GL_USE_MISSING_GLYPH_NV, ~0, emScale); |
| |
| Given a range of glyphs loaded as path objects, (kerned) spacing |
| information can now be queried for the string: |
| |
| glGetPathSpacingNV(GL_ACCUM_ADJACENT_PAIRS_NV, |
| 7, GL_UNSIGNED_BYTE, "OpenGLL", // repeat L to get final spacing |
| glyphBase, |
| 1.0f, 1.0f, |
| GL_TRANSLATE_X_NV, |
| kerning); |
| |
| Using the range of glyphs, stenciling and covering the instanced |
| paths for "OpenGL" can be done this way: |
| |
| glStencilFillPathInstancedNV(6, GL_UNSIGNED_BYTE, "OpenGL", |
| glyphBase, |
| GL_PATH_FILL_MODE_NV, 0xFF, |
| GL_TRANSLATE_X_NV, xtranslate); |
| |
| glCoverFillPathInstancedNV(6, GL_UNSIGNED_BYTE, "OpenGL", |
| glyphBase, |
| GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV, |
| GL_TRANSLATE_X_NV, xtranslate); |
| |
| The "stencil" and "cover" steps can be combined in a single command: |
| |
| glStencilThenCoverFillPathInstancedNV(6, GL_UNSIGNED_BYTE, "OpenGL", |
| glyphBase, |
| GL_PATH_FILL_MODE_NV, 0xFF, |
| GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV |
| GL_TRANSLATE_X_NV, xtranslate); |
| |
| XXX add path clipping example to demonstrate glPathStencilFuncNV. |
| |
| New Procedures and Functions |
| |
| PATH SPECIFICATION COMMANDS |
| |
| EXPLICIT PATH DATA |
| |
| void PathCommandsNV(uint path, |
| sizei numCommands, const ubyte *commands, |
| sizei numCoords, enum coordType, |
| const void *coords); |
| void PathCoordsNV(uint path, |
| sizei numCoords, enum coordType, |
| const void *coords); |
| |
| void PathSubCommandsNV(uint path, |
| sizei commandStart, sizei commandsToDelete, |
| sizei numCommands, const ubyte *commands, |
| sizei numCoords, enum coordType, |
| const void *coords); |
| void PathSubCoordsNV(uint path, |
| sizei coordStart, |
| sizei numCoords, enum coordType, |
| const void *coords); |
| |
| STRING PATH DESCRIPTION |
| |
| void PathStringNV(uint path, enum format, |
| sizei length, const void *pathString); |
| |
| PATHS FROM FONT GLYPHS BY UNICODE CHARACTER POINT |
| |
| void PathGlyphsNV(uint firstPathName, |
| enum fontTarget, |
| const void *fontName, |
| bitfield fontStyle, |
| sizei numGlyphs, enum type, |
| const void *charcodes, |
| enum handleMissingGlyphs, |
| uint pathParameterTemplate, |
| float emScale); |
| void PathGlyphRangeNV(uint firstPathName, |
| enum fontTarget, |
| const void *fontName, |
| bitfield fontStyle, |
| uint firstGlyph, |
| sizei numGlyphs, |
| enum handleMissingGlyphs, |
| uint pathParameterTemplate, |
| float emScale); |
| |
| PATHS FROM FONT GLYPHS BY PER-FONT GLYPH INDEX |
| |
| enum PathGlyphIndexArrayNV(uint firstPathName, |
| enum fontTarget, |
| const void *fontName, |
| bitfield fontStyle, |
| uint firstGlyphIndex, |
| sizei numGlyphs, |
| uint pathParameterTemplate, |
| float emScale); |
| enum PathMemoryGlyphIndexArrayNV(uint firstPathName, |
| enum fontTarget, |
| sizeiptr fontSize, |
| const void *fontData, |
| sizei faceIndex, |
| uint firstGlyphIndex, |
| sizei numGlyphs, |
| uint pathParameterTemplate, |
| float emScale); |
| enum PathGlyphIndexRangeNV(enum fontTarget, |
| const void *fontName, |
| bitfield fontStyle, |
| uint pathParameterTemplate, |
| float emScale, |
| uint baseAndCount[2]); |
| |
| PATH SPECIFICATION WITH EXISTING PATHS |
| |
| void WeightPathsNV(uint resultPath, |
| sizei numPaths, |
| const uint paths[], const float weights[]); |
| void CopyPathNV(uint resultPath, uint srcPath); |
| void InterpolatePathsNV(uint resultPath, |
| uint pathA, uint pathB, |
| float weight); |
| void TransformPathNV(uint resultPath, |
| uint srcPath, |
| enum transformType, |
| const float *transformValues); |
| |
| PATH PARAMETER SPECIFICATION COMMANDS |
| |
| void PathParameterivNV(uint path, enum pname, const int *value); |
| void PathParameteriNV(uint path, enum pname, int value); |
| void PathParameterfvNV(uint path, enum pname, const float *value); |
| void PathParameterfNV(uint path, enum pname, float value); |
| |
| void PathDashArrayNV(uint path, |
| sizei dashCount, const float *dashArray); |
| |
| PATH NAME MANAGEMENT |
| |
| uint GenPathsNV(sizei range); |
| void DeletePathsNV(uint path, sizei range); |
| boolean IsPathNV(uint path); |
| |
| PATH STENCILING |
| |
| void PathStencilFuncNV(enum func, int ref, uint mask); |
| void PathStencilDepthOffsetNV(float factor, float units); |
| |
| void StencilFillPathNV(uint path, |
| enum fillMode, uint mask); |
| |
| void StencilStrokePathNV(uint path, |
| int reference, uint mask); |
| |
| void StencilFillPathInstancedNV(sizei numPaths, |
| enum pathNameType, const void *paths, |
| uint pathBase, |
| enum fillMode, uint mask, |
| enum transformType, |
| const float *transformValues); |
| |
| void StencilStrokePathInstancedNV(sizei numPaths, |
| enum pathNameType, const void *paths, |
| uint pathBase, |
| int reference, uint mask, |
| enum transformType, |
| const float *transformValues); |
| |
| PATH COVERING |
| |
| void PathCoverDepthFuncNV(enum zfunc); |
| |
| void PathColorGenNV(enum color, |
| enum genMode, |
| enum colorFormat, const float *coeffs); |
| void PathTexGenNV(enum texCoordSet, |
| enum genMode, |
| int components, const float *coeffs); |
| void PathFogGenNV(enum genMode); |
| |
| void CoverFillPathNV(uint path, enum coverMode); |
| |
| void CoverStrokePathNV(uint path, enum coverMode); |
| |
| void CoverFillPathInstancedNV(sizei numPaths, |
| enum pathNameType, const void *paths, |
| uint pathBase, |
| enum coverMode, |
| enum transformType, |
| const float *transformValues); |
| |
| void CoverStrokePathInstancedNV(sizei numPaths, |
| enum pathNameType, const void *paths, |
| uint pathBase, |
| enum coverMode, |
| enum transformType, |
| const float *transformValues); |
| |
| PATH STENCILING THEN COVERING |
| |
| void StencilThenCoverFillPathNV(uint path, enum fillMode, |
| uint mask, enum coverMode); |
| void StencilThenCoverStrokePathNV(uint path, int reference, |
| uint mask, enum coverMode); |
| void StencilThenCoverFillPathInstancedNV(sizei numPaths, |
| enum pathNameType, |
| const void *paths, |
| uint pathBase, |
| enum fillMode, uint mask, |
| enum coverMode, |
| enum transformType, |
| const float *transformValues); |
| void StencilThenCoverStrokePathInstancedNV(sizei numPaths, |
| enum pathNameType, |
| const void *paths, |
| uint pathBase, |
| int reference, uint mask, |
| enum coverMode, |
| enum transformType, |
| const float *transformValues); |
| |
| PATH COVERING OF GLSL FRAGMENT INPUTS |
| |
| void ProgramPathFragmentInputGenNV(uint program, |
| int location, |
| enum genMode, |
| int components, |
| const float *coeffs); |
| |
| PATH QUERIES |
| |
| void GetPathParameterivNV(uint path, enum pname, int *value); |
| void GetPathParameterfvNV(uint path, enum pname, float *value); |
| |
| void GetPathCommandsNV(uint path, ubyte *commands); |
| void GetPathCoordsNV(uint path, float *coords); |
| void GetPathDashArrayNV(uint path, float *dashArray); |
| |
| void GetPathMetricsNV(bitfield metricQueryMask, |
| sizei numPaths, |
| enum pathNameType, const void *paths, |
| uint pathBase, |
| sizei stride, |
| float *metrics); |
| void GetPathMetricRangeNV(bitfield metricQueryMask, |
| uint firstPathName, |
| sizei numPaths, |
| sizei stride, |
| float *metrics); |
| |
| void GetPathSpacingNV(enum pathListMode, |
| sizei numPaths, |
| enum pathNameType, const void *paths, |
| uint pathBase, |
| float advanceScale, |
| float kerningScale, |
| enum transformType, |
| float *returnedSpacing); |
| |
| void GetPathColorGenivNV(enum color, enum pname, int *value); |
| void GetPathColorGenfvNV(enum color, enum pname, float *value); |
| void GetPathTexGenivNV(enum texCoordSet, enum pname, int *value); |
| void GetPathTexGenfvNV(enum texCoordSet, enum pname, float *value); |
| |
| boolean IsPointInFillPathNV(uint path, |
| uint mask, float x, float y); |
| boolean IsPointInStrokePathNV(uint path, |
| float x, float y); |
| |
| float GetPathLengthNV(uint path, |
| sizei startSegment, sizei numSegments); |
| |
| boolean PointAlongPathNV(uint path, |
| sizei startSegment, sizei numSegments, |
| float distance, |
| float *x, float *y, |
| float *tangentX, float *tangentY); |
| |
| MATRIX SPECIFICATION |
| |
| void MatrixLoad3x2fNV(enum matrixMode, const float *m); |
| void MatrixLoad3x3fNV(enum matrixMode, const float *m); |
| void MatrixLoadTranspose3x3fNV(enum matrixMode, const float *m); |
| |
| void MatrixMult3x2fNV(enum matrixMode, const float *m); |
| void MatrixMult3x3fNV(enum matrixMode, const float *m); |
| void MatrixMultTranspose3x3fNV(enum matrixMode, const float *m); |
| |
| FLOATING-POINT PROGRAM RESOURCE QUERY |
| |
| void GetProgramResourcefvNV(uint program, enum programInterface, |
| uint index, sizei propCount, |
| const enum *props, sizei bufSize, |
| sizei *length, float *params); |
| |
| New Tokens |
| |
| Accepted in elements of the <commands> array parameter of |
| PathCommandsNV and PathSubCommandsNV: |
| |
| CLOSE_PATH_NV 0x00 |
| MOVE_TO_NV 0x02 |
| RELATIVE_MOVE_TO_NV 0x03 |
| LINE_TO_NV 0x04 |
| RELATIVE_LINE_TO_NV 0x05 |
| HORIZONTAL_LINE_TO_NV 0x06 |
| RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 |
| VERTICAL_LINE_TO_NV 0x08 |
| RELATIVE_VERTICAL_LINE_TO_NV 0x09 |
| QUADRATIC_CURVE_TO_NV 0x0A |
| RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B |
| CUBIC_CURVE_TO_NV 0x0C |
| RELATIVE_CUBIC_CURVE_TO_NV 0x0D |
| SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E |
| RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F |
| SMOOTH_CUBIC_CURVE_TO_NV 0x10 |
| RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 |
| SMALL_CCW_ARC_TO_NV 0x12 |
| RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 |
| SMALL_CW_ARC_TO_NV 0x14 |
| RELATIVE_SMALL_CW_ARC_TO_NV 0x15 |
| LARGE_CCW_ARC_TO_NV 0x16 |
| RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 |
| LARGE_CW_ARC_TO_NV 0x18 |
| RELATIVE_LARGE_CW_ARC_TO_NV 0x19 |
| CONIC_CURVE_TO_NV 0x1A |
| RELATIVE_CONIC_CURVE_TO_NV 0x1B |
| ROUNDED_RECT_NV 0xE8 |
| RELATIVE_ROUNDED_RECT_NV 0xE9 |
| ROUNDED_RECT2_NV 0xEA |
| RELATIVE_ROUNDED_RECT2_NV 0xEB |
| ROUNDED_RECT4_NV 0xEC |
| RELATIVE_ROUNDED_RECT4_NV 0xED |
| ROUNDED_RECT8_NV 0xEE |
| RELATIVE_ROUNDED_RECT8_NV 0xEF |
| RESTART_PATH_NV 0xF0 |
| DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 |
| DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 |
| RECT_NV 0xF6 |
| RELATIVE_RECT_NV 0xF7 |
| CIRCULAR_CCW_ARC_TO_NV 0xF8 |
| CIRCULAR_CW_ARC_TO_NV 0xFA |
| CIRCULAR_TANGENT_ARC_TO_NV 0xFC |
| ARC_TO_NV 0xFE |
| RELATIVE_ARC_TO_NV 0xFF |
| |
| Accepted by the <format> parameter of PathStringNV: |
| |
| PATH_FORMAT_SVG_NV 0x9070 |
| PATH_FORMAT_PS_NV 0x9071 |
| |
| Accepted by the <fontTarget> parameter of PathGlyphsNV, |
| PathGlyphRangeNV, and PathGlyphIndexRangeNV: |
| |
| STANDARD_FONT_NAME_NV 0x9072 |
| SYSTEM_FONT_NAME_NV 0x9073 |
| FILE_NAME_NV 0x9074 |
| |
| Accepted by the <fontTarget> parameter of PathMemoryGlyphIndexArrayNV: |
| |
| STANDARD_FONT_FORMAT_NV 0x936C |
| |
| Accepted by the <handleMissingGlyph> parameter of PathGlyphsNV and |
| PathGlyphRangeNV: |
| |
| SKIP_MISSING_GLYPH_NV 0x90A9 |
| USE_MISSING_GLYPH_NV 0x90AA |
| |
| Returned by PathGlyphIndexRangeNV: |
| |
| FONT_GLYPHS_AVAILABLE_NV 0x9368 |
| FONT_TARGET_UNAVAILABLE_NV 0x9369 |
| FONT_UNAVAILABLE_NV 0x936A |
| FONT_UNINTELLIGIBLE_NV 0x936B // once was FONT_CORRUPT_NV |
| INVALID_ENUM |
| INVALID_VALUE |
| OUT_OF_MEMORY |
| |
| Accepted by the <pname> parameter of PathParameterfNV, |
| PathParameterfvNV, GetPathParameterfvNV, PathParameteriNV, |
| PathParameterivNV, and GetPathParameterivNV: |
| |
| PATH_STROKE_WIDTH_NV 0x9075 |
| PATH_INITIAL_END_CAP_NV 0x9077 |
| PATH_TERMINAL_END_CAP_NV 0x9078 |
| PATH_JOIN_STYLE_NV 0x9079 |
| PATH_MITER_LIMIT_NV 0x907A |
| PATH_INITIAL_DASH_CAP_NV 0x907C |
| PATH_TERMINAL_DASH_CAP_NV 0x907D |
| PATH_DASH_OFFSET_NV 0x907E |
| PATH_CLIENT_LENGTH_NV 0x907F |
| PATH_DASH_OFFSET_RESET_NV 0x90B4 |
| |
| PATH_FILL_MODE_NV 0x9080 |
| PATH_FILL_MASK_NV 0x9081 |
| PATH_FILL_COVER_MODE_NV 0x9082 |
| PATH_STROKE_COVER_MODE_NV 0x9083 |
| PATH_STROKE_MASK_NV 0x9084 |
| PATH_STROKE_BOUND_NV 0x9086 |
| |
| Accepted by the <pname> parameter of PathParameterfNV and |
| PathParameterfvNV: |
| |
| PATH_END_CAPS_NV 0x9076 |
| PATH_DASH_CAPS_NV 0x907B |
| |
| Accepted by the <fillMode> parameter of StencilFillPathNV and |
| StencilFillPathInstancedNV: |
| |
| INVERT |
| COUNT_UP_NV 0x9088 |
| COUNT_DOWN_NV 0x9089 |
| PATH_FILL_MODE_NV see above |
| |
| Accepted by the <color> parameter of PathColorGenNV, |
| GetPathColorGenivNV, and GetPathColorGenfvNV: |
| |
| PRIMARY_COLOR 0x8577 // from OpenGL 1.3 |
| PRIMARY_COLOR_NV 0x852C // from NV_register_combiners |
| SECONDARY_COLOR_NV 0x852D // from NV_register_combiners |
| |
| Accepted by the <genMode> parameter of PathColorGenNV, PathTexGenNV, |
| ProgramPathFragmentInputGenNV: |
| |
| NONE |
| EYE_LINEAR |
| OBJECT_LINEAR |
| PATH_OBJECT_BOUNDING_BOX_NV 0x908A |
| CONSTANT |
| |
| Accepted by the <coverMode> parameter of CoverFillPathNV and |
| CoverFillPathInstancedNV: |
| |
| CONVEX_HULL_NV 0x908B |
| BOUNDING_BOX_NV 0x908D |
| PATH_FILL_COVER_MODE_NV see above |
| |
| Accepted by the <coverMode> parameter of CoverStrokePathNV and |
| CoverStrokePathInstancedNV: |
| |
| CONVEX_HULL_NV see above |
| BOUNDING_BOX_NV see above |
| PATH_STROKE_COVER_MODE_NV see above |
| |
| Accepted by the <transformType> parameter of |
| StencilFillPathInstancedNV, StencilStrokePathInstancedNV, |
| CoverFillPathInstancedNV, and CoverStrokePathInstancedNV: |
| |
| NONE |
| TRANSLATE_X_NV 0x908E |
| TRANSLATE_Y_NV 0x908F |
| TRANSLATE_2D_NV 0x9090 |
| TRANSLATE_3D_NV 0x9091 |
| AFFINE_2D_NV 0x9092 |
| AFFINE_3D_NV 0x9094 |
| TRANSPOSE_AFFINE_2D_NV 0x9096 |
| TRANSPOSE_AFFINE_3D_NV 0x9098 |
| |
| Accepted by the <transformType> parameter of TransformPathNV: |
| |
| NONE |
| TRANSLATE_X_NV see above |
| TRANSLATE_Y_NV see above |
| TRANSLATE_2D_NV see above |
| TRANSLATE_3D_NV see above |
| AFFINE_2D_NV see above |
| AFFINE_3D_NV see above |
| TRANSPOSE_AFFINE_2D_NV see above |
| TRANSPOSE_AFFINE_3D_NV see above |
| |
| Accepted by the <type> or <pathNameType> parameter of |
| StencilFillPathInstancedNV, StencilStrokePathInstancedNV, |
| CoverFillPathInstancedNV, CoverStrokePathInstancedNV, |
| GetPathMetricsNV, and GetPathSpacingNV: |
| |
| UTF8_NV 0x909A |
| UTF16_NV 0x909B |
| |
| Accepted by the <coverMode> parameter of CoverFillPathInstancedNV: |
| |
| CONVEX_HULL_NV see above |
| BOUNDING_BOX_NV see above |
| BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C |
| PATH_FILL_COVER_MODE_NV see above |
| |
| Accepted by the <coverMode> parameter of CoverStrokePathInstancedNV: |
| |
| CONVEX_HULL_NV see above |
| BOUNDING_BOX_NV see above |
| BOUNDING_BOX_OF_BOUNDING_BOXES_NV see above |
| PATH_STROKE_COVER_MODE_NV see above |
| |
| Accepted by the <pname> parameter of GetPathParameterfvNV and |
| GetPathParameterivNV: |
| |
| PATH_COMMAND_COUNT_NV 0x909D |
| PATH_COORD_COUNT_NV 0x909E |
| PATH_DASH_ARRAY_COUNT_NV 0x909F |
| |
| PATH_COMPUTED_LENGTH_NV 0x90A0 |
| |
| PATH_OBJECT_BOUNDING_BOX_NV see above |
| PATH_FILL_BOUNDING_BOX_NV 0x90A1 |
| PATH_STROKE_BOUNDING_BOX_NV 0x90A2 |
| |
| Accepted by the <value> parameter of PathParameterfNV, |
| PathParameterfvNV, PathParameteriNV, and PathParameterivNV |
| when <pname> is one of PATH_END_CAPS_NV, PATH_INTIAL_END_CAP_NV, |
| PATH_TERMINAL_END_CAP_NV, PATH_DASH_CAPS_NV, PATH_INITIAL_DASH_CAP_NV, |
| and PATH_TERMINAL_DASH_CAP_NV: |
| |
| FLAT |
| SQUARE_NV 0x90A3 |
| ROUND_NV 0x90A4 |
| TRIANGULAR_NV 0x90A5 |
| |
| Accepted by the <value> parameter of PathParameterfNV, |
| PathParameterfvNV, PathParameteriNV, and PathParameterivNV |
| when <pname> is PATH_JOIN_STYLE_NV: |
| |
| NONE |
| ROUND_NV see above |
| BEVEL_NV 0x90A6 |
| MITER_REVERT_NV 0x90A7 |
| MITER_TRUNCATE_NV 0x90A8 |
| |
| Accepted by the <value> parameter of PathParameterfNV, |
| PathParameterfvNV, PathParameteriNV, and PathParameterivNV when |
| <pname> is PATH_DASH_OFFSET_RESET_NV: |
| |
| MOVE_TO_RESETS_NV 0x90B5 |
| MOVE_TO_CONTINUES_NV 0x90B6 |
| |
| Accepted by the <fontStyle> parameter of PathGlyphsNV, |
| PathGlyphRangeNV, and PathGlyphIndexRangeNV: |
| |
| NONE |
| BOLD_BIT_NV 0x01 |
| ITALIC_BIT_NV 0x02 |
| |
| Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, |
| GetInteger64v, GetFloatv, and GetDoublev: |
| |
| PATH_ERROR_POSITION_NV 0x90AB |
| |
| PATH_FOG_GEN_MODE_NV 0x90AC |
| |
| PATH_STENCIL_FUNC_NV 0x90B7 |
| PATH_STENCIL_REF_NV 0x90B8 |
| PATH_STENCIL_VALUE_MASK_NV 0x90B9 |
| |
| PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD |
| PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE |
| |
| PATH_COVER_DEPTH_FUNC_NV 0x90BF |
| |
| Accepted as a bit within the <metricQueryMask> parameter of |
| GetPathMetricRangeNV or GetPathMetricsNV: |
| |
| // per-glyph metrics |
| GLYPH_WIDTH_BIT_NV 0x01 |
| GLYPH_HEIGHT_BIT_NV 0x02 |
| GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 |
| GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 |
| GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 |
| GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 |
| GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 |
| GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 |
| GLYPH_HAS_KERNING_BIT_NV 0x100 |
| |
| // per-font face metrics |
| FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 |
| FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 |
| FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 |
| FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 |
| FONT_UNITS_PER_EM_BIT_NV 0x00100000 |
| FONT_ASCENDER_BIT_NV 0x00200000 |
| FONT_DESCENDER_BIT_NV 0x00400000 |
| FONT_HEIGHT_BIT_NV 0x00800000 |
| FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 |
| FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 |
| FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 |
| FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 |
| FONT_HAS_KERNING_BIT_NV 0x10000000 |
| FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 |
| |
| Accepted by the <pathListMode> parameter of GetPathSpacingNV: |
| |
| ACCUM_ADJACENT_PAIRS_NV 0x90AD |
| ADJACENT_PAIRS_NV 0x90AE |
| FIRST_TO_REST_NV 0x90AF |
| |
| Accepted by the <pname> parameter of GetPathColorGenivNV, |
| GetPathColorGenfvNV, GetPathTexGenivNV and GetPathTexGenfvNV: |
| |
| PATH_GEN_MODE_NV 0x90B0 |
| PATH_GEN_COEFF_NV 0x90B1 |
| |
| Accepted by the <pname> parameter of GetPathColorGenivNV and |
| GetPathColorGenfvNV: |
| |
| PATH_GEN_COLOR_FORMAT_NV 0x90B2 |
| |
| Accepted by the <pname> parameter of GetPathTexGenivNV and |
| GetPathTexGenfvNV: |
| |
| PATH_GEN_COMPONENTS_NV 0x90B3 |
| |
| Accepted by the <programInterface> parameter of GetProgramInterfaceiv, |
| GetProgramResourceIndex, GetProgramResourceName, GetProgramResourceiv, |
| GetProgramResourcefvNV, and GetProgramResourceLocation: |
| |
| FRAGMENT_INPUT_NV 0x936D |
| |
| Accepted in the <props> array of GetProgramResourceiv: |
| |
| PATH_GEN_MODE_NV see above |
| PATH_GEN_COMPONENTS_NV see above |
| |
| Accepted in the <props> array of GetProgramResourcefvNV: |
| |
| PATH_GEN_COEFF_NV see above |
| |
| Additions to Chapter 2 of the OpenGL 3.2 (unabridged) Specification |
| (OpenGL Operation) |
| |
| Add to the end of Section 2.12.1 (Matrices) with |
| EXT_direct_state_access language applied... |
| |
| "The command |
| |
| void MatrixLoad3x2fNV(enum matrixMode, const float *m); |
| |
| is equivalent to: |
| |
| const float equiv_3x2matrix[16] = { |
| m[0], m[2], 0, m[4], |
| m[1], m[3], 0, m[5], |
| 0, 0, 1, 0, |
| 0, 0, 0, 1 |
| }; |
| MatrixLoadTransposefEXT(matrixMode, equiv_3x2matrix); |
| |
| The command |
| |
| void MatrixLoad3x3fNV(enum matrixMode, const float *m); |
| |
| is equivalent to: |
| |
| const float equiv_3x3matrix[16] = { |
| m[0], m[3], 0, m[6], |
| m[1], m[4], 0, m[7], |
| 0, 0, 1, 0, |
| m[2], m[5], 0, m[8], |
| }; |
| MatrixLoadTransposefEXT(matrixMode, equiv_3x3matrix); |
| |
| The command |
| |
| void MatrixLoadTranspose3x3fNV(enum matrixMode, const float *m); |
| |
| is equivalent to: |
| |
| const float equiv_3x3matrix[16] = { |
| m[0], m[1], 0, m[2], |
| m[3], m[4], 0, m[5], |
| 0, 0, 1, 0, |
| m[6], m[7], 0, m[8], |
| }; |
| MatrixLoadTransposefEXT(matrixMode, equiv_3x3matrix); |
| |
| The command |
| |
| void MatrixMult3x2fNV(enum matrixMode, const float *m); |
| |
| is equivalent to: |
| |
| const float equiv_3x2matrix[16] = { |
| m[0], m[2], 0, m[4], |
| m[1], m[3], 0, m[5], |
| 0, 0, 1, 0, |
| 0, 0, 0, 1 |
| }; |
| MatrixMultTransposefEXT(matrixMode, equiv_3x2matrix); |
| |
| The command |
| |
| void MatrixMult3x3fNV(enum matrixMode, const float *m); |
| |
| is equivalent to: |
| |
| const float equiv_3x3matrix[16] = { |
| m[0], m[3], 0, m[6], |
| m[1], m[4], 0, m[7], |
| 0, 0, 1, 0, |
| m[2], m[5], 0, m[8], |
| }; |
| MatrixMultTransposefEXT(matrixMode, equiv_3x3matrix); |
| |
| The command |
| |
| void MatrixMultTranspose3x3fNV(enum matrixMode, const float *m); |
| |
| is equivalent to: |
| |
| const float equiv_3x3matrix[16] = { |
| m[0], m[1], 0, m[2], |
| m[3], m[4], 0, m[5], |
| 0, 0, 1, 0, |
| m[6], m[7], 0, m[8], |
| }; |
| MatrixMultTransposefEXT(matrixMode, equiv_3x3matrix);" |
| |
| Modify the ARB_program_interface_query language as follows... |
| |
| Add to the "query properties of the interfaces of a program object" |
| paragraph, so the "supported values of <programInterface>" includes: |
| |
| * FRAGMENT_INPUT_NV corresponds to the set of active input variables |
| used by the fragment shader stage of <program> (if a fragment |
| stage exists). (This may be different from PROGRAM_INPUT except |
| when the first shader stage is the fragment stage when they will |
| be identical.) |
| |
| Change this sentence about when locations are assigned to include |
| FRAGMENT_INPUT_NV so it reads: |
| |
| "When a program is linked successfully, active variables in the |
| UNIFORM, PROGRAM_INPUT, FRAGMENT_INPUT_NV, PROGRAM_OUTPUT interface, |
| or in any of the subroutine uniform interfaces, are assigned one or |
| more signed integer /locations/." |
| |
| Amend Table X.1 "GetProgramResourceiv properties and supported |
| interfaces" to add FRAGMENT_INPUT_NV to all the properties that |
| allow PROGRAM_INPUT. Specifically: |
| |
| * NAME_LENGTH |
| * TYPE |
| * ARRAY_SIZE |
| * REFERENCED_BY_*_SHADER |
| * LOCATION |
| * IS_PER_PATCH (will always be false for FRAGMENT_INPUT_NV) |
| |
| Further amend Table X.1 "GetProgramResourceiv properties with two |
| more properties for fragment input path generation state: |
| |
| Property Supported Interfaces |
| --------------------------- ---------------------------------------- |
| PATH_GEN_MODE_NV FRAGMENT_INPUT_NV |
| PATH_GEN_COMPONENTS_NV FRAGMENT_INPUT_NV |
| |
| Amend the discussion of GetProgramResourceiv properties, adding: |
| |
| "For the property PATH_GEN_MODE_NV, a single integer identifying |
| the path generation mode of an active variable is written to |
| <params>. The integer returned is one of NONE, OBJECT_LINEAR, |
| PATH_OBJECT_BOUNDING_BOX_NV, or EYE_LINEAR based on how |
| ProgramPathFragmentInputGenNV last specified the program resource's |
| path generation mode. The initial state is NONE. |
| |
| For the property PATH_GEN_COMPONENTS_NV, a single integer identifying |
| the number of generated path components an active variable is written |
| to <params>. The integer returned is between 0 and 4 based on how |
| ProgramPathFragmentInputGenNV last specified the program resource's |
| path generation number of components. The initial state is 0." |
| |
| Amend the list of tokens supported for the <programInterface> parameter of |
| GetProgramResourceLocation to include FRAGMENT_INPUT_NV so the relevant |
| sentence reads: |
| |
| "For GetProgramResourceLocation, <programInterface> must be one |
| of UNIFORM, PROGRAM_INPUT, FRAGMENT_INPUT_NV, PROGRAM_OUTPUT, |
| VERTEX_SUBROUTINE_UNIFORM, TESS_CONTROL_SUBROUTINE_UNIFORM, |
| TESS_EVALUATION_SUBROUTINE_UNIFORM, GEOMETRY_SUBROUTINE_UNIFORM, |
| FRAGMENT_SUBROUTINE_UNIFORM, or COMPUTE_SUBROUTINE_UNIFORM." |
| |
| After the discussion of GetProgramResourceiv, add: |
| |
| "The command |
| |
| void GetProgramResourcefvNV(uint program, enum programInterface, |
| uint index, sizei propCount, |
| const enum *props, sizei bufSize, |
| sizei *length, float *params); |
| |
| operates in the same manner as GetProgramResourceiv expect the |
| returned parameters values are floating-point and the only valid |
| value of <programInterface> is FRAGMENT_INPUT_NV and the only valid value |
| for the elements of the <props> array is PATH_GEN_COEFF_NV; otherwise |
| INVALID_ENUM is generated. |
| |
| For the property PATH_GEN_COEFF_NV, sixteen floating-point values |
| are written to <params> (limited to writing <bufSize> floating-point |
| values)." |
| |
| Additions to Chapter 3 of the OpenGL 3.2 (unabridged) Specification |
| (Rasterization) |
| |
| Append to the end of the "Shader Inputs" subsection of Section 3.12.2 |
| "Shader Execution": |
| |
| The command |
| |
| void ProgramPathFragmentInputGenNV(uint program, |
| int location, |
| enum genMode, |
| int components, |
| const float *coeffs); |
| |
| controls how a user-defined (non-built-in) fragment input of a |
| GLSL program object is computed for fragment shading operations that |
| occur as a result of CoverFillPathNV or CoverStrokePathNV. |
| |
| /program/ names a GLSL program object. If /program/ has not been |
| successfully linked, the error INVALID_OPERATION is generated. |
| |
| The given fragment input generation state is loaded into the fragment |
| input variable location identified by /location/. This location |
| is a value returned either by GetProgramResourceLocation with a |
| /programInterface/ of FRAGMENT_INPUT_NV and a given fragment shader |
| input variable name or by GetProgramResourceiv with FRAGMENT_INPUT_NV |
| for the /programInterface/ and LOCATION for the property for a given |
| fragment input resource index. |
| |
| If the value of location is -1, the ProgramPathFragmentInputGenNV command |
| will silently ignore the command, and the program's path fragment input |
| generation state will not be changed. |
| |
| If any of the following conditions occur, an INVALID_OPERATION error |
| is generated by the ProgramPathFragmentInputGenNV, and no state is changed: |
| |
| * if the size indicated in the /components/ of the |
| ProgramPathFragmentInputGenNV command used does not match the |
| size of the fragment input scalar or vector declared in the |
| shader, |
| |
| * if the fragment input declared in the shader is not |
| single-precision floating-point, or |
| |
| * if no fragment input variable with a location of /location/ |
| exists in the program object named by /program/ and location |
| is not -1, or |
| |
| * if the fragment input declared in the shader is a built-in |
| variables (i.e. prefixed by "gl_"). |
| |
| When covering paths, fragment input variables are interpolated at |
| each shaded fragment based on the corresponding fragment input |
| generation state specified by ProgramPathFragmentInputGenNV for |
| each respective fragment input. |
| |
| The /genMode/, /components/, and /coeffs/ parameters are used to |
| generate the fragment input variable values identically as the |
| PathTexGenNV command's corresponding parameters except it is a |
| fragment input that is generated rather than a texture coordinate set |
| (see the "TEXTURE COORDINATE SET GENERATION FOR PATH COVER COMMANDS" |
| discussion in section 5.X.2.2 "Path Covering"). Because there is |
| no associated texture coordinate set, the sc, tc, rc, and qc values |
| when discussing PathTexGenNV are always zero when generating fragment |
| input variables. |
| |
| When covering paths, if a fragment input variable has not had its |
| path fragment input generation state successfully generated, it as |
| if the values of this variable are always initialized to zero when |
| the fragment shader is executing. |
| |
| Also when covering paths, GLSL fragment shaders support the following |
| built-in fragment input variables: |
| |
| in vec4 gl_TexCoord[gl_MaxTextureCoords]; |
| in vec4 gl_Color |
| in vec4 gl_FrontColor; |
| in vec4 gl_BackColor; |
| in vec4 gl_SecondaryColor; |
| in vec4 gl_FrontSecondaryColor; |
| in vec4 gl_BackSecondaryColor; |
| in float gl_FogFragCoord; |
| |
| These respectively are initialized to the fragment input generated |
| coordinates of PathTexGenNV, PathColorGenNV for GL_PRIMARY_COLOR_NV |
| (front or back), PathColorGenNV for GL_SECONDARY_COLOR_NV (front or |
| back), and glPathFogGenNV." |
| |
| Additions to Chapter 4 of the OpenGL 3.2 (unabridged) Specification |
| (Per-Fragment Operations and the Frame Buffer) |
| |
| None |
| |
| Additions to Chapter 5 of the OpenGL 3.2 (unabridged) Specification |
| (Special Functions) |
| |
| -- Insert section 5.X "Path Rendering" after 5.3 "Feedback" |
| |
| 5.X Path Rendering |
| |
| 5.X.1 Path Specification |
| |
| PATH COMMANDS |
| |
| Paths are specified as a sequence of path commands; each path command |
| has an associated sequence of floating-point coordinates with the |
| number of such coordinates depending on the specific path command. |
| Coordinates are specified in a sequence independent from the path |
| command sequence; coordinates from the coordinate sequence are matched |
| up with (associated with) commands, in the order of the command, |
| with coordinates extracted from the front of the coordinate sequence. |
| |
| Valid path commands are listed in table 5.pathCommands. Each path |
| command is listed with its associated token, description, character |
| alias, count of associated coordinates. |
| |
| As an example of how path commands associated with path coordinates, |
| if the command sequence was MOVE_TO_NV, LINE_TO_NV, CUBIC_CURVE_TO_NV, |
| CLOSE_PATH_NV and the coordinates were 1, 2, 3, 4, 5, 6, 7, 8, 9, |
| 10, the MOVE_TO_NV command would be matched to coordinates 1 and 2, |
| LINE_TO_NV would be matched to 3 and 4, CUBIC_CURVE_TO_NV would be |
| matched to 5, 6, 7, 8, 9, 10, and CLOSE_PATH_NV would be matched to |
| no coordinates. |
| |
| Path commands are processed in their sequence order to generate the |
| path's outline. The outline generation process maintains three 2D |
| (x,y) state variables for each path processed: the start position |
| (sp), the current position (cp), and the prior end point (pep); |
| /sp/, /cp/ and /pep/ are initially (0,0) when a path starts being |
| processed. |
| |
| Table 5.pathCommands: Path Commands |
| |
| Character Coordinate |
| Token Description alias count |
| ========================== ===================== ========== ========== |
| MOVE_TO_NV Absolute move 'M' 2 |
| current point |
| RELATIVE_MOVE_TO_NV Relative move 'm' 2 |
| current point |
| -------------------------- --------------------- ---------- ---------- |
| CLOSE_PATH_NV Close path 'Z' or 'z' 0 |
| RESTART_PATH_NV Reset the path - 0 |
| -------------------------- --------------------- ---------- ---------- |
| LINE_TO_NV Absolute line 'L' 2 |
| RELATIVE_LINE_TO_NV Relative line 'l' 2 |
| -------------------------- --------------------- ---------- ---------- |
| HORIZONTAL_LINE_TO_NV Absolute horizontal 'H' 1 |
| line |
| RELATIVE_HORIZONTAL- Relative horizontal 'h' 1 |
| _LINE_TO_NV line |
| VERTICAL_LINE_TO_NV Absolute vertical 'V' 1 |
| line |
| RELATIVE_VERTICAL- Relative vertical 'v' 1 |
| _LINE_TO_NV line |
| -------------------------- --------------------- ---------- ---------- |
| QUADRATIC_CURVE_TO_NV Absolute quadratic 'Q' 4 |
| Bezier segment |
| RELATIVE- Relative quadratic 'q' 4 |
| _QUADRATIC_CURVE_TO_NV Bezier segment |
| -------------------------- --------------------- ---------- ---------- |
| CUBIC_CURVE_TO_NV Absolute cubic 'C' 6 |
| Bezier segment |
| RELATIVE_CUBIC_CURVE_TO_NV Relative cubic 'c' 6 |
| Bezier segment |
| -------------------------- --------------------- ---------- ---------- |
| SMOOTH- Absolute smooth 'T' 2 |
| _QUADRATIC_CURVE_TO_NV quadratic Bezier |
| segment |
| RELATIVE_SMOOTH- Relative smooth 't' 2 |
| _QUADRATIC_CURVE_TO_NV quadratic Bezier |
| segment |
| -------------------------- --------------------- ---------- ---------- |
| SMOOTH- Absolute smooth 'S' 4 |
| _CUBIC_CURVE_TO_NV cubic Bezier segment |
| RELATIVE_SMOOTH- Relative smooth 's' 4 |
| _CUBIC_CURVE_TO_NV cubic Bezier segment |
| -------------------------- --------------------- ---------- ---------- |
| SMALL_CCW_ARC_TO_NV Absolute small-sweep - 5 |
| counterclockwise |
| partial elliptical |
| arc segment |
| RELATIVE- Relative small-sweep - 5 |
| _SMALL_CCW_ARC_TO_NV counterclockwise |
| partial elliptical |
| arc segment |
| SMALL_CW_ARC_TO_NV Absolute small-sweep - 5 |
| clockwise partial |
| elliptical arc |
| segment |
| RELATIVE- Relative small-sweep - 5 |
| _SMALL_CW_ARC_TO_NV clockwise partial |
| elliptical arc |
| segment |
| LARGE_CCW_ARC_TO_NV Absolute large-sweep - 5 |
| counterclockwise |
| partial elliptical |
| arc segment |
| RELATIVE- Relative large-sweep - 5 |
| _LARGE_CCW_ARC_TO_NV counterclockwise |
| partial elliptical |
| arc segment |
| LARGE_CW_ARC_TO_NV Absolute large-sweep - 5 |
| clockwise partial |
| elliptical arc |
| segment |
| RELATIVE- Relative large-sweep - 5 |
| _LARGE_CW_ARC_TO_NV clockwise partial |
| elliptical arc |
| segment |
| -------------------------- --------------------- ---------- ---------- |
| CONIC_CURVE_TO_NV Absolute conic 'W' 5 |
| (rational Bezier) |
| segment |
| RELATIVE- Relative conic 'w' 5 |
| _CONIC_CURVE_TO_NV (rational Bezier) |
| segment |
| -------------------------- --------------------- ---------- ---------- |
| ROUNDED_RECT_NV Absolute rounded - 5 |
| rectangle with |
| uniform circular |
| corners (1 radius) |
| RELATIVE_ROUNDED_RECT_NV Relative rounded - 5 |
| rectangle with |
| uniform circular |
| corners (1 radius) |
| ROUNDED_RECT2_NV Absolute rounded - 6 |
| rectangle with |
| uniform elliptical |
| corners (2 x&y radii) |
| RELATIVE_ROUNDED_RECT2_NV Relative rounded - 6 |
| rectangle with |
| uniform elliptical |
| corners (2 x&y radii) |
| ROUNDED_RECT4_NV Absolute rounded - 8 |
| rectangle with |
| varying circular |
| corners (4 radii) |
| RELATIVE_ROUNDED_RECT4_NV Relative rounded - 8 |
| rectangle with |
| varying circular |
| corners (4 radii) |
| ROUNDED_RECT8_NV Absolute rounded - 12 |
| rectangle with |
| varying elliptical |
| corners (8 radii) |
| RELATIVE_ROUNDED_RECT8_NV Relative rounded - 12 |
| rectangle with |
| varying elliptical |
| corners (8 radii) |
| -------------------------- --------------------- ---------- ---------- |
| DUP_FIRST_- Absolute cubic Bezier - 4 |
| CUBIC_CURVE_TO_NV segment, duplicating |
| first control point |
| DUP_LAST_CUBIC_CURVE_TO_NV Absolute cubic Bezier - 4 |
| segment, duplicating |
| last control point |
| RECT_NV Closed absolute - 4 |
| rectangle |
| RELATIVE_RECT_NV Closed relative - 4 |
| rectangle |
| -------------------------- --------------------- ---------- ---------- |
| CIRCULAR_CCW_ARC_TO_NV Absolute - 5 |
| counterclockwise |
| circular arc segment |
| CIRCULAR_CW_ARC_TO_NV Absolute clockwise - 5 |
| circular arc segment |
| CIRCULAR_TANGENT_ARC_TO_NV Absolute circular - 5 |
| tangential |
| arc segment |
| -------------------------- --------------------- ---------- ---------- |
| ARC_TO_NV Absolute general 'A' 7 |
| elliptical arc |
| RELATIVE_ARC_TO_NV Relative general 'a' 7 |
| elliptical arc |
| -------------------------- --------------------- ---------- ---------- |
| |
| Table 5.pathEquations provides for each path command, as relevant, |
| the command's path segment parametric equation, equations for the |
| updated current point (ncp) and equations for the updated prior |
| end point (npep). After each command in a path is processed in the |
| sequence, the new current point, prior end point, and start point |
| (if changed) update the current point, prior end point, and start |
| point for the next path command to be processed in the sequence. So: |
| |
| cp = ncp |
| pep = npep |
| |
| Each path segment parametric equation is parameterized by a variable |
| /t/ ranging from 0.0 to 1.0. So the outline is traced by evaluating |
| each path command's path segment parametric equation continuously |
| as /t/ varies from 0.0 to 1.0. |
| |
| With the exception of the MOVE_TO_NV, RELATIVE_MOVE_TO_NV, |
| RESTART_PATH_NV, RECT_NV, RELATIVE_RECT_NV, ROUNDED_RECT_NV, |
| RELATIVE_ROUNDED_RECT_NV, ROUNDED_RECT2_NV, RELATIVE_ROUNDED_RECT2_NV, |
| ROUNDED_RECT4_NV, RELATIVE_ROUNDED_RECT4_NV, ROUNDED_RECT8_NV, |
| RELATIVE_ROUNDED_RECT8_NV, CIRCULAR_CCW_ARC_TO_NV, and |
| CIRCULAR_CW_ARC_TO_NV commands, the commands are specified such that |
| C0 continuity of the outline is guaranteed at path command segment |
| end-points. |
| |
| The MOVE_TO_NV, RELATIVE_MOVE_TO_NV, RESTART_PATH_NV, RECT_NV, |
| RELATIVE_RECT_NV, ROUNDED_RECT_NV, RELATIVE_ROUNDED_RECT_NV, |
| ROUNDED_RECT2_NV, RELATIVE_ROUNDED_RECT2_NV, |
| ROUNDED_RECT4_NV, RELATIVE_ROUNDED_RECT4_NV, ROUNDED_RECT8_NV, |
| RELATIVE_ROUNDED_RECT8_NV, CIRCULAR_CCW_ARC_TO_NV, and |
| CIRCULAR_CW_ARC_TO_NV commands update the start position (sp) to |
| the value of these command's new current point (ncp). |
| |
| The MOVE_TO_NV, RELATIVE_MOVE_TO_NV, RECT_NV, |
| RELATIVE_RECT_NV, ROUNDED_RECT_NV, RELATIVE_ROUNDED_RECT_NV, |
| ROUNDED_RECT2_NV, RELATIVE_ROUNDED_RECT2_NV, |
| ROUNDED_RECT4_NV, RELATIVE_ROUNDED_RECT4_NV, ROUNDED_RECT8_NV, |
| RELATIVE_ROUNDED_RECT8_NV, commands unconditionally change the start |
| position (sp) to value of these command's new current point (ncp) so: |
| |
| sp = ncp |
| |
| The CIRCULAR_CCW_ARC_TO_NV and CIRCULAR_CW_ARC_TO_NV commands |
| conditionally change sp to the command's ncp but only the sp has not |
| been specified by any prior command other than CLOSE_PATH_NV in the |
| path's command sequence since the beginning of the path's command |
| sequence or last RESTART_PATH_NV. When these circular arc commands |
| change the sp to the command's ncp, it implies the initial implicit |
| line these commands generate from sp to ncp will be zero length. |
| (This behavior is to match the semantics of PostScript.) |
| |
| Moving of the start position creates a discontinuity in the outline |
| so starts a new subpath within the path. |
| |
| Table 5.pathEquations: Path Equations |
| |
| Path segment new current new prior end |
| Token parametric equation point equation point equation |
| ========================== ====================================== ================== ======================= |
| MOVE_TO_NV - ncp.x = c[0] npep.x = c[0] |
| ncp.y = c[1] npep.y = c[1] |
| RELATIVE_MOVE_TO_NV - ncp.x = cp.x+c[0] npep.x = cp.x+c[0] |
| ncp.y = cp.y+c[1] npep.y = cp.y+c[1] |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| CLOSE_PATH_NV x = (1-t)*cp.x + t*sp.x ncp.x = sp.x npep.x = sp.x |
| y = (1-t)*cp.y + t*sp.y ncp.y = sp.y npep.y = sp.y |
| RESTART_PATH_NV - ncp.x = 0 npep.x = 0 |
| ncp.y = 0 npep.y = 0 |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| LINE_TO_NV x = (1-t)*cp.x + t*c[0] ncp.x = c[0] npep.x = c[0] |
| y = (1-t)*cp.y + t*c[1] ncp.y = c[1] npep.y = c[1] |
| RELATIVE_LINE_TO_NV x = (1-t)*cp.x + t*(c[0]+cp.x) ncp.x = cp.x+c[0] npep.x = cp.x+c[0] |
| y = (1-t)*cp.y + t*(c[1]+cp.y) ncp.y = cp.y+c[1] npep.y = cp.y+c[1] |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| HORIZONTAL_LINE_TO_NV x = (1-t)*cp.x + t*sp.x ncp.x = c[0] npep.x = c[0] |
| y = cp.y ncp.y = cp.y npep.y = cp.y |
| RELATIVE_HORIZONTAL- x = (1-t)*cp.x + t*(c[0]+cp.x) ncp.x = cp.x+c[0] npep.x = cp.x+c[0] |
| _LINE_TO_NV y = cp.y ncp.y = cp.y npep.y = cp.y |
| VERTICAL_LINE_TO_NV x = cp.x ncp.x = cp.x npep.x = cp.x |
| y = (1-t)*cp.y + t*sp.y ncp.y = c[0] npep.y = c[0] |
| RELATIVE_VERTICAL- x = cp.x ncp.x = cp.x npep.x = cp.x |
| _LINE_TO_NV y = (1-t)*cp.y + t*(c[0]+cp.y) ncp.y = cp.y+c[0] npep.y = cp.y+c[0] |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| QUADRATIC_CURVE_TO_NV x = (1-t)^2*cp.x + ncp.x = c[2] npep.x = c[0] |
| 2*(1-t)*t*c[0] + ncp.y = c[3] npep.y = c[1] |
| t^2*c[2] |
| y = (1-t)^2*cp.y + |
| 2*(1-t)*t*c[1] + |
| t^2*c[3] |
| RELATIVE- x = (1-t)^2*cp.x + ncp.x = cp.x+c[2] npep.x = cp.x+c[0] |
| _QUADRATIC_CURVE_TO_NV 2*(1-t)*t*(c[0]+cp.x) + ncp.y = cp.x+c[3] npep.y = cp.y+c[1] |
| t^2*(c[2]+cp.x) |
| y = (1-t)^2*cp.y + |
| 2*(1-t)*t*(c[1]+cp.y) + |
| t^2*(c[3]+cp.y) |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| CUBIC_CURVE_TO_NV x = (1-t)^3*cp.x + ncp.x = c[4] npep.x = c[2] |
| 3*(1-t)^2*t*c[0] + ncp.y = c[5] npep.y = c[3] |
| 3*(1-t)*t^2*c[2] + |
| t^3*c[4] |
| y = (1-t)^3*cp.y + |
| 3*(1-t)^2*t*c[1] + |
| 3*(1-t)*t^2*c[3] + |
| t^3*c[5] |
| RELATIVE_CUBIC_CURVE_TO_NV x = (1-t)^3*cp.x + ncp.x = cp.x+c[4] npep.x = cp.x+c[2] |
| 3*(1-t)^2*t*(c[0]+cp.x) + ncp.y = cp.y+c[5] npep.y = cp.y+c[3] |
| 3*(1-t)*t^2*(c[2]+cp.x) + |
| t^3*(c[4]+cp.x) |
| y = (1-t)^3*cp.y + |
| 3*(1-t)^2*t*(c[1]+cp.y) + |
| 3*(1-t)*t^2*(c[3]+cp.y) + |
| t^3*(c[5]+cp.y) |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| SMOOTH- x = (1-t)^2*cp.x + ncp.x = c[0] npep.x = 2*cp.x-pep.x |
| _QUADRATIC_CURVE_TO_NV 2*(1-t)*t*(2*cp.x-pep.x) + ncp.y = c[1] npep.y = 2*cp.y-pep.y |
| t^2*c[0] |
| y = (1-t)^2*cp.y + |
| 2*(1-t)*t*(2*cp.y-pep.y) + |
| t^2*c[1] |
| RELATIVE_SMOOTH- x = (1-t)^2*cp.x + ncp.x = cp.x+c[0] npep.x = 2*cp.x-pep.x |
| QUADRATIC_CURVE_TO_NV 2*(1-t)*t*(2*cp.x-pep.x) + ncp.y = cp.y+c[1] npep.y = 2*cp.y-pep.y |
| t^2*(c[0]+cp.x) |
| y = (1-t)^2*cp.y + |
| 2*(1-t)*t*(2*cp.y-pep.y) + |
| t^2*(c[1]+cp.y) |
| |
| SMOOTH- x = (1-t)^3*cp.x + ncp.x = c[2] npep.x = c[0] |
| _CUBIC_CURVE_TO_NV 3*(1-t)^2*t*(2*cp.x-pep.x) + ncp.y = c[3] npep.y = c[1] |
| 3*(1-t)*t^2*c[0] + |
| t^3*c[2] |
| y = (1-t)^3*cp.y + |
| 3*(1-t)^2*t*(2*cp.y-pep.y) + |
| 3*(1-t)*t^2*c[1] + |
| t^3*c[3] |
| RELATIVE_SMOOTH- x = (1-t)^3*cp.x + ncp.x = cp.x+c[2] npep.x = cp.x+c[0] |
| _CUBIC_CURVE_TO_NV 3*(1-t)^2*t*(2*cp.x-pep.x) + ncp.y = cp.y+c[3] npep.y = cp.y+c[1] |
| 3*(1-t)*t^2*(c[0]+cp.x) + |
| t^3*(c[2]+cp.x) |
| y = (1-t)^3*cp.y + |
| 3*(1-t)^2*t*(2*cp.y-pep.y) + |
| 3*(1-t)*t^2*(c[1]+cp.y) + |
| t^3*(c[3]+cp.y) |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| SMALL_CCW_ARC_TO_NV x = arc_x(c,rv,rh,phi, ncp.x = c[3] npep.x = c[3] |
| theta1,dtheta,t) ncp.y = c[4] npep.y = c[4] |
| y = arc_y(c,rv,rh,phi, |
| theta1,dtheta,t) |
| RELATIVE- x = arc_x(c,rv,rh,phi, ncp.x = c[3] npep.x = cp.x+c[3] |
| _SMALL_CCW_ARC_TO_NV theta1,dtheta,t) ncp.y = c[4] npep.y = cp.y+c[4] |
| y = arc_y(c,rv,rh,phi, |
| theta1,dtheta,t) |
| SMALL_CW_ARC_TO_NV x = arc_x(c,rv,rh,phi, ncp.x = c[3] npep.x = c[3] |
| theta1,dtheta,t) ncp.y = c[4] npep.y = c[4] |
| y = arc_y(c,rv,rh,phi, |
| theta1,dtheta,t) |
| RELATIVE- x = arc_x(c,rv,rh,phi, ncp.x = c[3] npep.x = cp.x+c[3] |
| _SMALL_CW_ARC_TO_NV theta1,dtheta,t) ncp.y = c[4] npep.y = cp.y+c[4] |
| y = arc_y(c,rv,rh,phi, |
| theta1,dtheta,t) |
| LARGE_CCW_ARC_TO_NV x = arc_x(c,rv,rh,phi, ncp.x = c[3] npep.x = c[3] |
| theta1,dtheta,t) ncp.y = c[4] npep.y = c[4] |
| y = arc_y(c,rv,rh,phi, |
| theta1,dtheta,t) |
| RELATIVE- x = arc_x(c,rv,rh,phi, ncp.x = c[3] npep.x = cp.x+c[3] |
| _LARGE_CCW_ARC_TO_NV theta1,dtheta,t) ncp.y = c[4] npep.y = cp.y+c[4] |
| y = arc_y(c,rv,rh,phi, |
| theta1,dtheta,t) |
| LARGE_CW_ARC_TO_NV x = arc_x(c,rv,rh,phi, ncp.x = c[3] npep.x = c[3] |
| theta1,dtheta,t) ncp.y = c[4] npep.y = c[4] |
| y = arc_y(c,rv,rh,phi, |
| theta1,dtheta,t) |
| RELATIVE- x = arc_x(c,rv,rh,phi, ncp.x = c[3] npep.x = cp.x+c[3] |
| _SMALL_CW_ARC_TO_NV theta1,dtheta,t) ncp.y = c[4] npep.y = cp.y+c[4] |
| y = arc_y(c,rv,rh,phi, |
| theta1,dtheta,t) |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| CONIC_CURVE_TO_NV WHEN c[4] > 0: ncp.x = c[2] npep.x = c[0] |
| x = ( (1-t)^2*cp.x + ncp.y = c[3] npep.y = c[1] |
| 2*(1-t)*t*c[0]*c[4] + |
| t^2*c[2] ) / |
| ( (1-t)^2 + |
| 2*(1-t)*t*c[4] + |
| t^2*c[2] ) |
| y = ( 1-t)^2*cp.y + |
| 2*(1-t)*t*c[1]*w + |
| t^2*c[3] ) / |
| ( (1-t)^2 + |
| 2*(1-t)*t*c[4] + |
| t^2*c[2] ), |
| OTHERWISE: |
| x = (1-t)*cp.x + t*c[2] |
| y = (1-t)*cp.y + t*c[3] |
| RELATIVE- WHEN c[4] > 0: ncp.x = cp.x+c[2] npep.x = cp.x+c[0] |
| _CONIC_CURVE_TO_NV x = ( (1-t)^2*cp.x + ncp.y = cp.y+c[3] npep.y = cp.y+c[1] |
| 2*(1-t)*t*(c[0]+cp.x)*c[4] + |
| t^2*(c[2]+cp.x) ) / |
| ( (1-t)^2 + |
| 2*(1-t)*t*c[4] + |
| t^2*c[2] ) |
| y = ( 1-t)^2*cp.y + |
| 2*(1-t)*t*c[1]*w + |
| t^2*c[3] ) / |
| ( (1-t)^2 + |
| 2*(1-t)*t*c[4] + |
| t^2*c[2] ), |
| OTHERWISE: |
| x = (1-t)*cp.x + t*(c[2]+cp.x) |
| y = (1-t)*cp.y + t*(c[3]+cp.y) |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| ROUNDED_RECT_NV x = rrect(c[0], c[1], c[2], c[3], ncp.x = C_ll.x npep.x = C_ll.x |
| c[4], c[4], c[4], c[4], ncp.y = C_ll.y npep.y = C_ll.y |
| c[4], c[4], c[4], c[4], t).x |
| y = rrect(c[0], c[1], c[2], c[3], |
| c[4], c[4], c[4], c[4], |
| c[4], c[4], c[4], c[4], t).y |
| RELATIVE_ROUNDED_RECT_NV x = rrect(c[0]+cp.x, c[1]+cp.y, ncp.x = C_ll.x npep.x = C_ll.x |
| c[2], c[3], ncp.y = C_ll.y npep.y = C_ll.y |
| c[4], c[4], c[4], c[4], |
| c[4], c[4], c[4], c[4], t).x |
| y = rrect(c[0]+cp.x, c[1]+cp.y, |
| c[2], c[3], |
| c[4], c[4], c[4], c[4], |
| c[4], c[4], c[4], c[4], t).y |
| ROUNDED_RECT2_NV x = rrect(c[0], c[1], c[2], c[3], ncp.x = C_ll.x npep.x = C_ll.x |
| c[4], c[5], c[4], c[5], ncp.y = C_ll.y npep.y = C_ll.y |
| c[4], c[5], c[4], c[5], t).x |
| y = rrect(c[0], c[1], c[2], c[3], |
| c[4], c[5], c[4], c[5], |
| c[4], c[5], c[4], c[5], t).y |
| RELATIVE_ROUNDED_RECT2_NV x = rrect(c[0]+cp.x, c[1]+cp.y, ncp.x = C_ll.x npep.x = C_ll.x |
| c[2], c[3], ncp.y = C_ll.y npep.y = C_ll.y |
| c[4], c[5], c[4], c[5], |
| c[4], c[5], c[4], c[5], t).x |
| y = rrect(c[0]+cp.x, c[1]+cp.y, |
| c[2], c[3], |
| c[4], c[5], c[4], c[5], |
| c[4], c[5], c[4], c[5], t).y |
| ROUNDED_RECT4_NV x = rrect(c[0], c[1], c[2], c[3], ncp.x = C_ll.x npep.x = C_ll.x |
| c[4], c[4], c[5], c[5], ncp.y = C_ll.y npep.y = C_ll.y |
| c[6], c[6], c[7], c[7], t).x |
| y = rrect(c[0], c[1], c[2], c[3], |
| c[4], c[4], c[5], c[5], |
| c[6], c[6], c[7], c[7], t).y |
| RELATIVE_ROUNDED_RECT4_NV x = rrect(c[0]+cp.x, c[1]+cp.y, ncp.x = C_ll.x npep.x = C_ll.x |
| c[2], c[3], ncp.y = C_ll.y npep.y = C_ll.y |
| c[4], c[4], c[5], c[5], |
| c[6], c[6], c[7], c[7], t).x |
| y = rrect(c[0]+cp.x, c[1]+cp.y, |
| c[2], c[3], |
| c[4], c[4], c[5], c[5], |
| c[6], c[6], c[7], c[7], t).y |
| ROUNDED_RECT8_NV x = rrect(c[0], c[1], c[2], c[3], ncp.x = C_ll.x npep.x = C_ll.x |
| c[4], c[5], c[6], c[7], ncp.y = C_ll.y npep.y = C_ll.y |
| c[8], c[9], |
| c[10], c[11], t).x |
| y = rrect(c[0], c[1], c[2], c[3], |
| c[4], c[5], c[6], c[7], |
| c[8], c[9], |
| c[10], c[11], t).y |
| RELATIVE_ROUNDED_RECT8_NV x = rrect(c[0]+cp.x, c[1]+cp.y, ncp.x = C_ll.x npep.x = C_ll.x |
| c[2], c[3], ncp.y = C_ll.y npep.y = C_ll.y |
| c[4], c[5], c[6], c[7], |
| c[8], c[9], |
| c[10], c[11], t).x |
| y = rrect(c[0]+cp.x, c[1]+cp.y, |
| c[2], c[3], |
| c[4], c[5], c[6], c[7], |
| c[8], c[9], |
| c[10], c[11], t).y |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| DUP_FIRST- x = (1-t)^3*cp.x + ncp.x = c[2] npep.x = c[0] |
| CUBIC_CURVE_TO_NV 3*(1-t)^2*t*cp.x + ncp.y = c[3] npep.y = c[1] |
| 3*(1-t)*t^2*c[0] + |
| t^3*c[2] |
| y = (1-t)^3*cp.y + |
| 3*(1-t)^2*t*cp.y + |
| 3*(1-t)*t^2*c[1] + |
| t^3*c[3] |
| DUP_LAST_CUBIC_CURVE_TO_NV x = (1-t)^3*cp.x + ncp.x = c[2] npep.x = c[2] |
| 3*(1-t)^2*t*c[0] + ncp.y = c[3] npep.y = c[3] |
| 3*(1-t)*t^2*c[2] + |
| t^3*c[2] |
| y = (1-t)^3*cp.y + |
| 3*(1-t)^2*t*c[1] + |
| 3*(1-t)*t^2*c[3] + |
| t^3*c[3] |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| RECT_NV / (1-4*t)*c[0] + ncp.x = c[0] npep.x = c[0] |
| | 4*t*(c[0]+c[2]), t<=0.25 ncp.y = c[1] npep.y = c[1] |
| x = < c[0]+c[2], 0.25<t<=0.5 |
| | (1-4*t-2)*(c[0]+c[2]) + |
| | (4*t-2)*c[0], 0.5 <t<=0.75 |
| \ c[0], 0.75<t |
| / c[1], t<=0.25 |
| | (1-4*t-1)*c[1] + |
| y = < (4*t-1)*(c[1]+c[3]), 0.25<t<=0.5 |
| | c[1]+c[3], 0.5 <t<=0.75 |
| | (1-4*t-3)*(c[1]+c[3]) + |
| \ (4*t-3)*c[1], 0.75<t |
| RELATIVE_RECT_NV / (1-4*t)*(c[0]+cp.x) + ncp.x = cp.x+c[0] npep.x = cp.x+c[0] |
| | 4*t*(c[0]+c[2]+cp.x), t<=0.25 ncp.y = cp.y+c[1] npep.y = cp.y+c[1] |
| x = < c[0]+c[2]+cp.x, 0.25<t<=0.5 |
| | (1-4*t-2)*(c[0]+c[2]+cp.x) + |
| | (4*t-2)*(c[0]+cp.x), 0.5<t<=0.75 |
| \ c[0]+cp.x, 0.75<t |
| / c[1]+cp.y, t<=0.25 |
| | (1-4*t-1)*(c[1]+cp.y) + |
| y = < (4*t-1)*(c[1]+c[3]+cp.y), |
| | 0.25<t<=0.5 |
| | c[1]+c[3]+cp.y, 0.5<t<=0.75 |
| | (1-4*t-3)*(c[1]+c[3]+cp.y) + |
| \ (4*t-3)*(c[1]+cp.y), 0.75<t |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| CIRCULAR_CCW_ARC_TO_NV / (1-2*t)*cp.x + 2*t*A.x, t<=0.5 ncp.x = B.x npep.x = B.x |
| x = { ncp.y = B.y npep.x = B.y |
| \ arc_x(c,rv,rh,phi,theta1, |
| \ dtheta,t*2-1) t>=0.5 |
| / (1-2*t)*cp.y + 2*t*A.y, t<=0.5 |
| y = { |
| \ arc_y(c,rv,rh,phi,theta1, |
| \ dtheta,t*2-1), t>=0.5 |
| CIRCULAR_CW_ARC_TO_NV / (1-2*t)*cp.x + 2*t*A.x, t<=0.5 ncp.x = B.x npep.x = B.x |
| x = { ncp.y = B.y npep.x = B.y |
| \ arc_x(c,rv,rh,phi,theta1, |
| \ dtheta,t*2-1) t>=0.5 |
| / (1-2*t)*cp.y + 2*t*A.y, t<=0.5 |
| y = { |
| \ arc_y(c,rv,rh,phi,theta1, |
| \ dtheta,t*2-1), t>=0.5 |
| CIRCULAR_TANGENT_ARC_TO_NV / (1-2*t)*cp.x + 2*t*C.x, t<=0.5 ncp.x = D.x npep.x = D.x |
| x = { ncp.y = D.y npep.x = D.y |
| \ arc_x(c,rv,rh,phi,theta1, |
| \ dtheta,t*2-1), t>=0.5 |
| / (1-2*t)*cp.y + 2*t*C.y, t<=0.5 |
| y = { |
| \ arc_y(c,rv,rh,phi,theta1, |
| \ dtheta,t*2-1), t>=0.5 |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| ARC_TO_NV x = arc_x(c,rv,rh,phi, ncp.x = c[5] npep.x = c[5] |
| theta1,dtheta,t) ncp.y = c[6] npep.y = c[6] |
| y = arc_y(c,rv,rh,phi, |
| theta1,dtheta,t) |
| RELATIVE_ARC_TO_NV x = arc_x(c,rv,rh,phi, ncp.x = cp.x+c[5] npep.x = cp.x+c[5] |
| theta1,dtheta,t) ncp.y = cp.y+c[6] npep.y = cp.y+c[6] |
| y = arc_y(c,rv,rh,phi, |
| theta1,dtheta,t) |
| -------------------------- -------------------------------------- ------------------ ----------------------- |
| |
| In the equations in Table 5.pathEquations, c[i] is the /i/th (base |
| zero) coordinate of the coordinate sequence for the command; /cp/ |
| is the 2D (x,y) current position from the prior command (for the |
| first command of a path object, /cp/ is (0,0)); /sp/ is the 2D (x,y) |
| start position for the current contour (for the first command of a |
| path object, /sp/ is (0,0)); /pep/ is the 2D (x,y) prior end position |
| from the prior end position (for the first command of a path object, |
| /pep/ is (0,0)); and /ncp/ is the 2D (x,y) "new" current position |
| that will become the current position for the subsequent command; |
| /npep/ is the 2D (x,y) "new" prior end position for the subsequent |
| command. The values /c/, /theta1/, /dtheta/ are explained in the |
| discussion of partial elliptical arc commands below. The values |
| of /rv/, /rh/, /phi/ come from Table 5.arcParameterSpecialization. |
| The values of /A/, /B/, /C/, and /D/ are discussed in the context |
| of Table 5.arcParameterSpecialization. /C_ll/ is the lower-left |
| end-point defined for Equation 5.roundedRectangleContour. |
| |
| If a value specified for a coordinate (however the coordinate is |
| specified) or a value computed from these coordinates (as specified |
| in the discussion that follows) exceeds the implementation's maximum |
| representable value for a single-precision floating-point number, |
| the rendering behavior (discussed in section 5.X.2) of the specified |
| path and the value of said coordinate if queried (section 6.X.2) |
| is undefined. This is relevant because coordinates can be specified |
| explicitly but also relatively (by RELATIVE_* path commands) or |
| encoded in a string of otherwise arbitrary precision and range or |
| computed by weighting. |
| |
| ROUNDED RECTANGLE COMMAND DETAILS |
| |
| In all the rounded-rectangle path commands, the parametric segment |
| path equations in Table 5.pathEquations are expressed in terms of |
| the function /rrect/ that returns an (x,y) position on the rounded |
| rectangle when evaluated over the parametric range t=0..1. /rrect/ |
| is a spline of alternating rational quadratic Bezier segments and |
| linear segments that forms a closed contour. |
| |
| In addition to its parametric variable /t/, /rrect/ has 12 |
| parameters to which geometric properties can be ascribed when these |
| values are positive. (No restriction precludes these parameters |
| to be non-positive; negative and zero values are allowed and |
| supported.) (x,y) is the 2D location of the lower-left corner of the |
| rectangle tightly bounding the rounded rectangle contour; /w/ and /h/ |
| are the respective width and height of the same bounding rectangle. |
| /r_llx/, /r_lrx/, /r_urx/, and /r_ulx/ are the elliptical x-axis |
| radii corresponding to the lower-left, lower-right, upper-right, |
| and upper-left corners of the rounded rectangle; likewise /r_lly/, |
| /r_lry/, /r_ury/, and /r_uly/ are the elliptical y-axis for the |
| same corners. |
| |
| Equation 5.roundedRectangleContour |
| |
| rrect(x,y, / (1-t_0)*C_ll + t_0*A_lr, t=0/8..1/8 |
| w,h, | |
| r_llx,r_lly, | (1-t_1)^2*A_lr + (1-t_1)*t_1*B_lr*sqrt(2) + t_1^2*C_lr)/ |
| r_lrx,r_lry, = < ((1-t_1)^2 + (1-t_1)*t_1*sqrt(2) + t_1^2), t=1/8..2/8 |
| r_urx,r_ury, | |
| r_ulx,r_uly, | (1-t_2)*C_lr + t_2*A_ur, t=2/8..3/8 |
| t) | |
| | (1-t_3)^2*A_ur + (1-t_3)*t_3*B_ur*sqrt(2) + t_3^2*C_ur)/ |
| | ((1-t_3)^2 + (1-t_3)*t_3*sqrt(2) + t_3^2), t=3/8..4/8 |
| | |
| | (1-t_4)*C_ur + t_4*A_ul, t=4/8..5/8 |
| | |
| | (1-t_5)^2*A_ul + (1-t_5)*t_5*B_ul*sqrt(2) + t_5^2*C_ul)/ |
| | ((1-t_5)^2 + (1-t_5)*t_5*sqrt(2) + t_5^2), t=5/8..6/8 |
| | |
| | (1-t_6)*C_ul + t_6*A_ll, t=6/8..7/8 |
| | |
| | (1-t_7)^2*A_ll + (1-t_7)*t_7*B_ll*sqrt(2) + t_7^2*C_ll)/ |
| \ ((1-t_7)^2 + (1-t_7)*t_7*sqrt(2) + t_7^2), t=7/8..1 |
| |
| where |
| |
| t_i = 8*t - i |
| |
| A_ll = (x,y-r_lly), h<0 |
| (x,y+r_lly), otherwise |
| B_ll = (x,y) |
| C_ll = (x-r_llx,y), w<0 |
| (x+r_llx,y), otherwise |
| |
| A_lr = (x+w+r_lrx,y), w<0 |
| (x+w-r_lrx,y), otherwise |
| B_lr = (x+w,y) |
| C_lr = (x+w,y-r_lry), h<0 |
| (x+w,y+r_lry), otherwise |
| |
| A_ur = (x+w,y+h-r_ury*sign(h)), h<0 |
| (x+w,y+h-r_ury*sign(h)), otherwise |
| B_ur = (x+w,y+h) |
| C_ur = (x+w+r_urx,y+h), w<0 |
| (x+w-r_urx,y+h), otherwise |
| |
| A_ul = (x-r_ulx,y+h), w<0 |
| (x+r_ulx,y+h), otherwise |
| B_ul = (x,y+h) |
| C_ul = (x,y+h+r_uly), h<0 |
| (x,y+h-r_uly), otherwise |
| |
| Consider /t_i/ to be a subparmetric range within /t/ where /t_i/ |
| ranges over 0..1 for each spline segment of /rrect/. The 2D control |
| points /A_ll/ through /C_ul/ are shown in Figure 5.roundedRectangle, |
| where /ll/, /lr/, /ur/, and /ul/ correspond to lower-left, |
| lower-right, upper-right, and upper-left respectively. |
| |
| Figure 5.roundedRectangle: Geometric interpretation of Equation |
| 5.roundedRectangleContour parameters. |
| |
| _ r_ulx _ r_urx |
| / \ / \ |
| / \C_ul A_ur / \ |
| B_ul .-----.-----------------------.-----. B_ur \ |
| /| |\ | |
| r_uly < | | > r_ury | |
| \| |/ | |
| A_ul . . C_ur | |
| | | \ |
| | | > h |
| | | / |
| | | | |
| A_ll . . C_rl | |
| /| |\ | |
| r_lly < | | > r_rly | |
| \| |/ | |
| B_ll .-----.-----------------------.-----. B_rl / |
| & (x,y) \ /C_ll A_rl \ / |
| \_/ \_/ |
| r_llx r_rlx |
| \______________ __________________/ |
| \/ |
| w |
| |
| Note that the ROUNDED_RECT*_NV commands degenerate to the RECT_NV |
| command when all the radii are zero. |
| |
| PARTIAL ELLIPTICAL ARC COMMAND DETAILS |
| |
| In all the arc-based path commands, the parametric segment path |
| equations in Table 5.pathEquations are expressed in terms of the |
| functions /arc_x/ and /arc_y/. |
| |
| Equation 5.generalParametricArc |
| |
| arc_x(c,rv,rh,phi,theta1,dtheta,t) = cos(phi)*rh*cos(theta1+t*dtheta) - |
| sin(phi)*rv*sin(theta1+t*dtheta) + c.x |
| arc_y(c,rv,rh,phi,theta1,dtheta,t) = sin(phi)*rh*cos(theta1+t*dtheta) + |
| cos(phi)*rv*sin(theta1+t*dtheta) + c.y |
| |
| This general form of a parametric partial elliptical arc computes |
| (x,y) 2D positions on the arc as /t/ ranges from 0.0 to 1.0 inclusive. |
| |
| In addition to the varying /t/ parameter, these functions depend on |
| a 2D (x,y) center position /c/, a horizontal ellipse radius /rh/, |
| a vertical ellipse radius /rv/, a counterclockwise angle (in radians) |
| of an ellipse with respect to the x-axis /phi/, /theta1/ is the angle |
| (in radians) of the initial point on the partial arc, and /dtheta/ |
| is the difference between the angle (in radians) of the terminal |
| point on the partial arc and /theta1/. The larger of /rh/ and /rv/ |
| is the complete ellipse's major axis while the smaller of the two |
| is the complete ellipse's minor axis. |
| |
| How these additional dependent parameters for /arc_x/ and /arc_y/ |
| are determined depends on the specific arc path command as |
| detailed in Table 5.arcParameterSpecialization. Before explaining |
| how specific arc commands determine these dependent parameters, |
| the following discussion develops a general scheme for converting |
| general end-point representations of arcs to the partial elliptical |
| arc segment representation of Equation 5.generalParametricArc. |
| All the arc commands supported are specializations of this general |
| end-point representation. The general scheme is developed, specific |
| arc commands are specified as special cases of the general end-point |
| representation scheme for arcs. |
| |
| In general, consider seven scalar values (/x1/, /y1/, /x2/, |
| /y2/, /phi/, /fA/, and /fS/) fully parameterizing a given partial |
| elliptical arc: |
| |
| * a 2D position (x1,y1) at the start of a partial elliptical |
| arc segment |
| |
| * a 2D position (x2,y2) at the end of a partial elliptical |
| arc segment |
| |
| * /phi/ is the angle (in radians) from the x-axis of the path |
| space coordinate system to the x-axis of the axis-aligned ellipse |
| |
| * /fA/ is a boolean (the "large arc" flag) that is true when |
| the arc spans greater than 180 degrees; and otherwise false |
| if the arc sweeps 180 degrees or less |
| |
| * /fS/ is a boolean (the "sweep" flag) that is true when the |
| arc sweeps in a counterclockwise direction in path space |
| (so sweeps with increasing angles); and otherwise false |
| when the arc sweeps in a clockwise direction (so sweeps with |
| decreasing angles) |
| |
| Given this parameterization, the procedure below computes the /c/, |
| /rv/, /rh/, /phi/, /theta1/, and /dtheta/ parameters to represent |
| this same arc in the general parametric form of Equation |
| 5.generalParametricArc. |
| |
| Step 1: |
| |
| x1p = cos(phi)*(x1-x2)/2 + sin(phi)*(y1-y2)/2 |
| y1p = -sin(phi)*(x1-x2)/2 + cos(phi)*(y1-y2)/2 |
| |
| If /rh/, /rv/, and /phi/ are such that there is no solution |
| (basically, the ellipse is not big enough to reach from (x1,y1) |
| to (x2,y2), then the ellipse is scaled up uniformly until there |
| is exactly one solution (until the ellipse is just big enough) |
| in this manner: |
| |
| lambda = (x1p/rh)^2 + (y1p/rv)^2 |
| |
| / rh, lambda<=1 |
| rp.x = { |
| \ rh*sqrt(lambda), lambda>1 |
| |
| / rv, lambda<=1 |
| rp.y = { |
| \ rv*sqrt(lambda), lambda>1 |
| |
| Step 2: |
| |
| cp.x = fsgn*sqrt((rp.x^2*rp.y^2 - rp.x^2*y1p^2 - rp.y^2*x1p^2) / |
| (rp.x^2*y1p^2 + rp.y^2*x1p^2) |
| ) * rp.x*y1p/rp.y |
| cp.y = fsgn*sqrt((rp.x^2*rp.y^2 - rp.x^2*y1p^2 - rp.y^2*x1p^2) / |
| (rp.x^2*y1p^2 + rp.y^2*x1p^2) |
| ) * -rp.y*x1p/rp.x |
| |
| where |
| |
| / +1, fA != fS |
| fsgn = { |
| \ -1, fA = fS |
| |
| Step 3: |
| |
| c.x = cos(phi)*cp.x - sin(phi)*cyp + (x1+x2)/2 |
| c.y = sin(phi)*cp.x + cos(phi)*cyp + (y1+y2)/2 |
| |
| In general, the angle between two vectors (u.x, u.y) and (v.x, v.y) |
| can be computed as |
| |
| / arcos(dot(u,v)/sqrt(dot(u,u))*sqrt(dot(v,v))), u.x*v.y-u.y*v.x>=0 |
| angle(u,v) = { |
| \ -arcos(dot(u,v)/sqrt(dot(u,u))*sqrt(dot(v,v))), u.x*v.y-u.y*v.x<0 |
| |
| Step 4: |
| |
| theta1 = angle([1,0], |
| [(x1p-cp.x)/r.x,(y1p-cp.y)/r.y]) |
| dangle = angle([(x1p-cp.x)/r.x,(y1p-cp.y)/r.y], |
| [(-x1p-cp.x)/r.x,(-y1p-cp.y)/r.y]) |
| |
| / dangle - 2*Pi, fS=false AND d>0 |
| / |
| / dangle, fS=false AND d<=0 |
| dtheta = { |
| \ dangle, fS=true AND d>=0 |
| \ |
| \ dangle + 2*Pi, fS=true AND d<0 |
| |
| The arc path commands allow arbitrary numeric values so when these |
| values result in invalid or out-of-range parameters when the above |
| steps are applied, the following further steps are taken to ensure |
| well-defined behavior. |
| |
| If (x1,y1) and (x2,y2) are identical, then this is equivalent to |
| omitting the arc segment entirely. |
| |
| If either of /rh/ or /rv/ is zero, the arc is treated as a straight |
| line segment from (x1,y1) to (x2,y2). |
| |
| Table 5.arcParameterSpecialization now maps the coordinate values |
| for each arc path command to the parameters of the arc end-point |
| parameterization above from which the arc's parametric representation |
| can be obtained. |
| |
| Table 5.arcParameterSpecialization: Arc Path Command |
| |
| Token (x1,y1) rh rv phi (x2,y2) fA fS |
| ---------------------------- ---------- --------- --------- ----------- ------------------- --------------- ------- |
| SMALL_CCW_ARC_TO_NV cp.x,cp.y abs(c[0]) abs(c[1]) c[2]*Pi/180 c[3],c[4] false true |
| RELATIVE_SMALL_CCW_ARC_TO_NV cp.x,cp.y abs(c[0]) abs(c[1]) c[2]*Pi/180 cp.x+c[3],cp.y+c[4] false true |
| SMALL_CW_ARC_TO_NV cp.x,cp.y abs(c[0]) abs(c[1]) c[2]*Pi/180 c[3],c[4] false false |
| RELATIVE_SMALL_CW_ARC_TO_NV cp.x,cp.y abs(c[0]) abs(c[1]) c[2]*Pi/180 cp.x+c[3],cp.y+c[4] false false |
| LARGE_CCW_ARC_TO_NV cp.x,cp.y abs(c[0]) abs(c[1]) c[2]*Pi/180 c[3],c[4] true true |
| RELATIVE_LARGE_CCW_ARC_TO_NV cp.x,cp.y abs(c[0]) abs(c[1]) c[2]*Pi/180 cp.x+c[3],cp.y+c[4] true true |
| LARGE_CW_ARC_TO_NV cp.x,cp.y abs(c[0]) abs(c[1]) c[2]*Pi/180 c[3],c[4] true false |
| RELATIVE_SMALL_CW_ARC_TO_NV cp.x,cp.y abs(c[0]) abs(c[1]) c[2]*Pi/180 cp.x+c[3],cp.y+c[4] true false |
| CIRCULAR_CCW_ARC_TO_NV A.x,A.y abs(c[2]) abs(c[2]) 0 B.x,B.y (c[4]-c[3])>180 true |
| CIRCULAR_CW_ARC_TO_NV A.x,A.y abs(c[2]) abs(c[2]) 0 B.x,B.y (c[4]-c[3])>180 false |
| CIRCULAR_TANGENT_ARC_TO_NV C.x,C.y abs(c[4]) abs(c[4]) 0 D.x,D.y false num>=0 |
| ARC_TO_NV cp.x,cp.y abs(c[0]) abs(c[1]) c[2]*Pi/180 c[5],c[6] c[3]!=0 c[4]!=0 |
| RELATIVE_ARC_TO_NV cp.x,cp.y abs(c[0]) abs(c[1]) c[2]*Pi/180 cp.x+c[5],cp.y+c[6] c[3]!=0 c[4]!=0 |
| |
| where, for CIRCULAR_CCW_ARC_TO_NV and CIRCULAR_CW_ARC_TO_NV, |
| |
| A = (c[0]+c[2]*cos(c[3]*Pi/180), |
| c[1]+c[2]*sin(c[3]*Pi/180)) |
| |
| B = (c[0]+c[2]*cos(c[4]*Pi/180), |
| c[1]+c[2]*sin(c[4]*Pi/180)) |
| |
| and C, D, and num, for CIRCULAR_TANGENT_ARC_TO_NV, are computed |
| through the following steps: |
| |
| Step 1: Compute two tangent vectors: |
| |
| d0.x = cp.x - c[0] |
| d0.y = cp.y - c[1] |
| d2.x = c[2] - c[0] |
| d2.y = c[3] - c[1] |
| |
| Step 2: Compute scaling factors for tangent vectors: |
| |
| num = d0.y*d2.x - d2.y*d0.x |
| denom = sqrt(dot(d0,d0)*dot(d2,d2)) - dot(d0,d2) |
| |
| dist = abs(c[4] * num/denom) |
| |
| l0 = dist/sqrt(dot(d0,d0)) * c[4]/abs(c[4]) |
| l2 = dist/sqrt(dot(d2,d2)) * c[4]/abs(c[4]) |
| |
| Step 3: Add scaled directions to the tangent vector intersection |
| point: |
| |
| / (c[0],c[1]) + d0 * l0, denom!=0 AND c[4]!=0 |
| C = { |
| \ (c[0],c[1]), denom==0 OR c[4]==0 |
| |
| / (c[0],c[1]) + d2 * l2, denom!=0 AND c[4]!=0 |
| D = { |
| \ (c[0],c[1]), denom==0 OR c[4]==0 |
| |
| PATH OBJECT SPECIFICATION |
| |
| Path objects can be specified in one of four ways: |
| |
| 1) explicitly from an array of commands and corresponding |
| coordinates, |
| |
| 2) from a string conforming to one of two supported grammars to |
| specify a string, |
| |
| 3) from a glyph within a font face from a system font or font file, |
| or |
| |
| 4) by linearly combining one or more existing path objects with |
| mutually consistent command sequences to form a new path. |
| |
| In any situation where a path object is specified or re-specified, |
| the command's parameters are re-initialized as discussed in section |
| 5.X.1.5 unless otherwise specified. However modification of path |
| commands and coordinates (section 5.X.1.4) does not modify path |
| parameters. |
| |
| 5.X.1.1 Explicit Path Specification |
| |
| The command |
| |
| void PathCommandsNV(uint path, |
| sizei numCommands, const ubyte *commands, |
| sizei numCoords, enum coordType, |
| const void *coords); |
| |
| specifies a new path object named /path/ where /numCommands/ |
| indicates the number of path commands, read from the array |
| /commands/, with which to initialize that path's command sequence. |
| These path commands reference coordinates read sequentially from the |
| /coords/ array. The type of the coordinates read from the /coords/ |
| array is determined by the /coordType/ parameter which must be |
| one of BYTE, UNSIGNED_BYTE, SHORT, UNSIGNED_SHORT, or FLOAT, |
| otherwise the INVALID_ENUM error is generated. |
| |
| The /numCommands/ elements of the /commands/ array must be tokens |
| or character in Table 5.pathCommands. The command sequence matches |
| the element order of the /commands/ array. Each command references |
| a number of coordinates specified by "Coordinate count" column of |
| Table 5.pathCommands, starting with the first (zero) element of |
| the /coords/ array and advancing by the coordinate count for each |
| command. If any of these /numCommands/ command values are not |
| listed in the "Token" or "Character aliases" columns of Table |
| 5.pathCommands, the INVALID_ENUM error is generated. |
| |
| The INVALID_OPERATION error is generated if /numCoords/ does not |
| equal the number of coordinates referenced by the command sequence |
| specified by /numCommands/ and /commands/ (so /numCoords/ provides a |
| sanity check that the /coords/ array is being interpreted properly). |
| The error INVALID_VALUE is generated if either /numCommands/ or |
| /numCoords/ is negative. |
| |
| If the PathCommandsNV command results in an error, the path object |
| named /path/ is not changed; if there is no error, the prior contents |
| of /path/, if /path/ was an existent path object, are lost and the |
| path object name /path/ becomes used. |
| |
| 5.X.1.2 String Path Specification |
| |
| The command |
| |
| void PathStringNV(uint path, enum format, |
| sizei length, const void *pathString); |
| |
| specifies a new path object named /path/ where /format/ must be |
| either PATH_FORMAT_SVG_NV or PATH_FORMAT_PS_NV, in which case the |
| /length/ and /pathString/ are interpreted according to grammars |
| specified in sections 5.X.1.2.1 and 5.X.1.2.2 respectively. |
| The INVALID_VALUE error is generated if /length/ is negative. |
| |
| If the PathStringNV command results in an error, the path object |
| named /path/ is not changed; if there is no error, the prior contents |
| of /path/, if /path/ was an existent path object, are lost and the |
| path object name /path/ becomes used. |
| |
| 5.X.1.2.1 Scalable Vector Graphics Path Grammar |
| |
| If the /format/ parameter of PathStringNV is PATH_FORMAT_SVG_NV, |
| the /pathString/ parameter is interpreted as a string of ubyte ASCII |
| characters with /length/ elements. |
| |
| This string must satisfy the "svg-path" production in the path |
| grammar below. This grammar is taken directly from the Scalable |
| Vector Graphics (SVG) 1.1 (April 30, 2009) specification. |
| |
| The following notation is used in the Backus-Naur Form (BNF) |
| description of the grammar for an SVG path string: |
| |
| * *: 0 or more |
| * +: 1 or more |
| * ?: 0 or 1 |
| * (): grouping |
| * ()^n: grouping with n repetitions where n is explained subsequently |
| * |: separates alternatives |
| * double quotes surround literals |
| * #x: prefixes an ASCII character value followed by hexadecimal |
| digits |
| * ..: means any of an inclusive range of ASCII characters, so |
| '0'..'9' means any digit character |
| |
| The following is the grammar for SVG paths. |
| |
| svg-path: |
| wsp* moveto-drawto-command-groups? wsp* |
| moveto-drawto-command-groups: |
| moveto-drawto-command-group |
| | moveto-drawto-command-group wsp* moveto-drawto-command-groups |
| moveto-drawto-command-group: |
| moveto wsp* drawto-commands? |
| drawto-commands: |
| drawto-command |
| | drawto-command wsp* drawto-commands |
| drawto-command: |
| closepath |
| | lineto |
| | horizontal-lineto |
| | vertical-lineto |
| | curveto |
| | smooth-curveto |
| | quadratic-bezier-curveto |
| | smooth-quadratic-bezier-curveto |
| | elliptical-arc |
| moveto: |
| ( "M" | "m" ) wsp* moveto-argument-sequence |
| moveto-argument-sequence: |
| coordinate-pair |
| | coordinate-pair comma-wsp? lineto-argument-sequence |
| closepath: |
| ("Z" | "z") |
| lineto: |
| ( "L" | "l" ) wsp* lineto-argument-sequence |
| lineto-argument-sequence: |
| coordinate-pair |
| | coordinate-pair comma-wsp? lineto-argument-sequence |
| horizontal-lineto: |
| ( "H" | "h" ) wsp* horizontal-lineto-argument-sequence |
| horizontal-lineto-argument-sequence: |
| coordinate |
| | coordinate comma-wsp? horizontal-lineto-argument-sequence |
| vertical-lineto: |
| ( "V" | "v" ) wsp* vertical-lineto-argument-sequence |
| vertical-lineto-argument-sequence: |
| coordinate |
| | coordinate comma-wsp? vertical-lineto-argument-sequence |
| curveto: |
| ( "C" | "c" ) wsp* curveto-argument-sequence |
| curveto-argument-sequence: |
| curveto-argument |
| | curveto-argument comma-wsp? curveto-argument-sequence |
| curveto-argument: |
| coordinate-pair comma-wsp? coordinate-pair comma-wsp? coordinate-pair |
| smooth-curveto: |
| ( "S" | "s" ) wsp* smooth-curveto-argument-sequence |
| smooth-curveto-argument-sequence: |
| smooth-curveto-argument |
| | smooth-curveto-argument comma-wsp? smooth-curveto-argument-sequence |
| smooth-curveto-argument: |
| coordinate-pair comma-wsp? coordinate-pair |
| quadratic-bezier-curveto: |
| ( "Q" | "q" ) wsp* quadratic-bezier-curveto-argument-sequence |
| quadratic-bezier-curveto-argument-sequence: |
| quadratic-bezier-curveto-argument |
| | quadratic-bezier-curveto-argument comma-wsp? |
| quadratic-bezier-curveto-argument-sequence |
| quadratic-bezier-curveto-argument: |
| coordinate-pair comma-wsp? coordinate-pair |
| smooth-quadratic-bezier-curveto: |
| ( "T" | "t" ) wsp* smooth-quadratic-bezier-curveto-argument-sequence |
| smooth-quadratic-bezier-curveto-argument-sequence: |
| coordinate-pair |
| | coordinate-pair comma-wsp? smooth-quadratic-bezier-curveto-argument-sequence |
| elliptical-arc: |
| ( "A" | "a" ) wsp* elliptical-arc-argument-sequence |
| elliptical-arc-argument-sequence: |
| elliptical-arc-argument |
| | elliptical-arc-argument comma-wsp? elliptical-arc-argument-sequence |
| elliptical-arc-argument: |
| nonnegative-number comma-wsp? nonnegative-number comma-wsp? |
| number comma-wsp flag comma-wsp flag comma-wsp coordinate-pair |
| coordinate-pair: |
| coordinate comma-wsp? coordinate |
| coordinate: |
| number |
| nonnegative-number: |
| integer-constant |
| | floating-point-constant |
| number: |
| sign? integer-constant |
| | sign? floating-point-constant |
| flag: |
| "0" | "1" |
| comma-wsp: |
| (wsp+ comma? wsp*) | (comma wsp*) |
| comma: |
| "," |
| integer-constant: |
| digit-sequence |
| floating-point-constant: |
| fractional-constant exponent? |
| | digit-sequence exponent |
| fractional-constant: |
| digit-sequence? "." digit-sequence |
| | digit-sequence "." |
| exponent: |
| ( "e" | "E" ) sign? digit-sequence |
| sign: |
| "+" | "-" |
| digit-sequence: |
| digit |
| | digit digit-sequence |
| digit: |
| "0".."9" |
| wsp: |
| (#x20 | #x9 | #xD | #xA) |
| |
| The processing of the BNF must consume as much of a given BNF |
| production as possible, stopping at the point when a character |
| is encountered which no longer satisfies the production. Thus, |
| in the string "M 100-200", the first coordinate for the "moveto" |
| consumes the characters "100" and stops upon encountering the minus |
| sign because the minus sign cannot follow a digit in the production |
| of a "coordinate". The result is that the first coordinate will be |
| "100" and the second coordinate will be "-200". |
| |
| Similarly, for the string "M 0.6.5", the first coordinate of the |
| "moveto" consumes the characters "0.6" and stops upon encountering |
| the second decimal point because the production of a "coordinate" |
| only allows one decimal point. The result is that the first coordinate |
| will be "0.6" and the second coordinate will be ".5". |
| |
| The grammar allows the string to be empty (zero length). This is |
| not an error, instead specifies a path with no commands. |
| |
| Table 5.svgCommands maps productions in the grammar above to the |
| path commands in Table 5.pathCommands; each such path command, with |
| its corresponding coordinates, is added to the path command sequence |
| of the path object. Each production listed in Table 5.svgCommands |
| consumes a number of coordinates consistent with the path command |
| token's coordinate count listed in Table 5.pathCommands. The |
| "coordinate" and "nonnegative-number" productions convert to a numeric |
| coordinate value in the obvious way. The "flag" production converts |
| "0" and "1" to numeric coordinate values zero and one respectively. |
| |
| Table 5.svgCommands: SVG Grammar Commands to Path Command Tokens |
| |
| Grammar's prior |
| Production command character Path command token |
| ------------------------------------------------- ----------------- ------------------------------------- |
| moveto-argument-sequence "M" MOVE_TO_NV |
| "m" RELATIVE_MOVE_TO_NV |
| closepath "Z" or "z" CLOSE_PATH_NV |
| lineto-argument-sequence "L" LINE_TO_NV |
| "l" RELATIVE_LINE_TO_NV |
| horizontal-lineto-argument-sequence "H" HORIZONTAL_LINE_TO_NV |
| "h" RELATIVE_HORIZONTAL_LINE_TO_NV |
| vertical-lineto-argument-sequence "V" VERTICAL_LINE_TO_NV |
| "v" RELATIVE_VERTICAL_LINE_TO_NV |
| quadratic-bezier-curveto-argument "Q" QUADRATIC_CURVE_TO_NV |
| "q" RELATIVE_QUADRATIC_CURVE_TO_NV |
| smooth-quadratic-bezier-curveto-argument-sequence "T" SMOOTH_QUADRATIC_CURVE_TO_NV |
| "t" RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV |
| curveto-argument "C" CUBIC_CURVE_TO_NV |
| "c" RELATIVE_CUBIC_CURVE_TO_NV |
| smooth-curveto-argument "S" SMOOTH_CUBIC_CURVE_TO_NV |
| "s" RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV |
| elliptical-arc-argument "A" ARC_TO_NV |
| "a" RELATIVE_ARC_TO_NV |
| |
| If the string fails to satisfy the svg-path production, the path |
| object named /path/ is not changed. The production may not be |
| satisfied for one of two reasons: either the grammar cannot be not |
| satisfied by the string, or the grammar is satisfied but there still |
| remain a non-zero number of characters in the string. Neither |
| failure to satisfy the production generates an error; instead the |
| PATH_ERROR_POSITION_NV state is set to the character offset where the |
| grammar was first not satisfied or where the grammar was exhausted. |
| If the string was parsed successfully and the command did not generate |
| an error, the PATH_ERROR_POSITION_NV state is set to negative one |
| to indicate success. |
| |
| 5.X.1.2.2 PostScript Path Grammar |
| |
| If the /format/ parameter of PathStringNV is PATH_FORMAT_PS_NV, |
| the /pathString/ parameter is interpreted as a string of ubyte ASCII |
| characters with /length/ elements. |
| |
| This string must satisfy the "ps-path" production in the path |
| grammar below. This grammar is parses path specified in PostScript's |
| subgrammar for user paths specified by "PostScript Language Reference |
| Manual" 3rd edition. |
| |
| The following is the grammar (using the same notation as section |
| 5.X.1.2.1) for PS paths with special support for binary encoding modes |
| (as explained below): |
| |
| ps-path: |
| ps-wsp* user-path? ps-wsp* |
| | ps-wsp* encoded-path ps-wsp* |
| user-path: |
| user-path-cmd |
| | user-path-cmd ps-wsp+ user-path |
| user-path-cmd: |
| setbbox |
| | ps-moveto |
| | rmoveto |
| | ps-lineto |
| | rlineto |
| | ps-curveto |
| | rcurveto |
| | arc |
| | arcn |
| | arct |
| | ps-closepath |
| | ucache |
| setbbox: |
| numeric-value numeric-value numeric-value numeric-value setbbox-cmd |
| setbbox-cmd: |
| "setbbox" |
| | #x92 #x8F |
| ps-moveto: |
| numeric-value numeric-value moveto-cmd |
| moveto-cmd: |
| "moveto" |
| | #x92 #x6B |
| rmoveto: |
| numeric-value numeric-value rmoveto-cmd |
| rmoveto-cmd: |
| "rmoveto" |
| | #x92 #x86 |
| ps-lineto: |
| numeric-value numeric-value lineto-cmd |
| lineto-cmd: |
| "lineto" |
| | #x92 #x63 |
| rlineto: |
| numeric-value numeric-value rlineto-cmd |
| rlineto-cmd: |
| "rlineto" |
| | #x92 #x85 |
| ps-curveto: |
| numeric-value numeric-value numeric-value numeric-value numeric-value numeric-value curveto-cmd |
| curveto-cmd: |
| "curveto" |
| | #x92 #x2B |
| rcurveto: |
| numeric-value numeric-value numeric-value numeric-value numeric-value numeric-value rcurveto-cmd |
| rcurveto-cmd: |
| "rcurveto" |
| | #x92 #x7A |
| arc: |
| numeric-value numeric-value numeric-value numeric-value numeric-value arc-cmd |
| arc-cmd: |
| "arc" |
| | #x92 #x05 |
| arcn: |
| numeric-value numeric-value numeric-value numeric-value numeric-value arcn-cmd |
| arcn-cmd: |
| "arcn" |
| | #x92 #x06 |
| arct: |
| numeric-value numeric-value numeric-value numeric-value numeric-value arct-cmd |
| arct-cmd: |
| "arct" |
| | #x92 #x07 |
| ps-closepath: |
| "closepath" |
| | #x92 #x16 |
| ucache: |
| "ucache" |
| | #x92 #xB1 |
| encoded-path: |
| data-array ps-wsp* operator-string |
| data-array: |
| "{" ps-wsp* numeric-value-sequence? "}" |
| | homogeneous-number-array |
| | ascii85-homogeneous-number-array |
| operator-string: |
| hexadecimal-binary-string |
| | ascii85-string |
| | short-binary-string |
| | be-long-binary-string |
| | le-long-binary-string |
| hexadecimal-binary-string: |
| "<" ps-wsp-chars* hexadecimal-sequence ps-wsp-chars* ">" |
| hexadecimal-sequence: |
| hexadecimal-digit |
| | hexadecimal-digit ps-wsp-chars* hexadecimal-sequence |
| hexadecimal-digit: |
| digit |
| | "a".."f" | |
| | "A".."F" |
| short-binary-string: |
| #x8E one-byte ( one-byte )^n |
| /where n is the value of the one-byte production decoded |
| as an unsigned integer, 0 through 255/ |
| be-long-binary-string: |
| #x8F two-bytes ( one-byte )^n |
| /where n is the value of the two-bytes production decoded |
| as an unsigned integer, 0 through 65535, decoded in |
| big-endian byte order/ |
| le-long-binary-string: |
| #x90 two-bytes ( one-byte )^n |
| /where n is the value of the two-bytes production decoded |
| as an unsigned integer, 0 through 65535, decoded in |
| little-endian byte order/ |
| numeric-value-sequence: |
| numeric-value: |
| | numeric-value numeric-value-sequence |
| numeric-value: |
| number ps-wsp+ |
| | radix-number ps-wsp+ |
| | be-integer-32bit |
| | le-integer-32bit |
| | be-integer-16bit |
| | le-integer-16bit |
| | le-integer-8bit |
| | be-fixed-16bit |
| | le-fixed-16bit |
| | be-fixed-32bit |
| | le-fixed-32bit |
| | be-float-ieee |
| | le-float-ieee |
| | native-float-ieee |
| be-integer-32bit: |
| #x84 four-bytes |
| le-integer-32bit: |
| #x85 four-bytes |
| be-integer-16bit: |
| #x86 two-bytes |
| le-integer-16bit: |
| #x87 two-bytes |
| le-integer-8bit: |
| #x88 one-byte |
| be-fixed-32bit: |
| #x89 #x0..#x1F four-bytes |
| le-fixed-32bit: |
| #x89 #x80..#x9F four-bytes |
| be-fixed-16bit: |
| #x89 #x20..#x2F two-bytes |
| le-fixed-16bit: |
| #x89 #xA0..#xAF two-bytes |
| be-float-ieee: |
| #x8A four-bytes |
| le-float-ieee: |
| #x8B four-bytes |
| native-float-ieee: |
| #x8C four-bytes |
| radix-number: |
| base "#" base-number |
| base: |
| digit-sequence |
| base-number: |
| base-digit-sequence |
| base-digit-sequence: |
| base-digit |
| | base-digit base-digit-sequence |
| base-digit: |
| digit |
| | "a".."z" |
| | "A".."Z" |
| homogeneous-number-array: |
| be-fixed-32bit-array |
| | be-fixed-16bit-array |
| | be-float-ieee-array |
| | native-float-ieee-array |
| | le-fixed-32bit-array |
| | le-fixed-16bit-array |
| | le-float-ieee-array |
| be-fixed-32bit-array: |
| #x95 #x0..#x1F two-bytes ( four-bytes )^n |
| /where n is the value of the two-bytes production decoded |
| as an unsigned integer, 0 through 65535, decoded in |
| big-endian byte order/ |
| be-fixed-16bit-array: |
| #x95 #x20..#x2F two-bytes ( two-bytes )^n |
| /where n is the value of the two-bytes production decoded |
| as an unsigned integer, 0 through 65535, decoded in |
| big-endian byte order/ |
| be-float-ieee-array: |
| #x95 #x30 two-bytes ( four-bytes )^n |
| /where n is the value of the two-bytes production decoded |
| as an unsigned integer, 0 through 65535, decoded in |
| big-endian byte order/ |
| le-fixed-32bit-array: |
| #x95 #x80..#x9F two-bytes ( four-bytes )^n |
| /where n is the value of the two-bytes production decoded |
| as an unsigned integer, 0 through 65535, decoded in |
| little-endian byte order/ |
| le-fixed-16bit-array: |
| #x95 #xA0..#xAF two-bytes ( two-bytes )^n |
| /where n is the value of the two-bytes production decoded |
| as an unsigned integer, 0 through 65535, decoded in |
| little-endian byte order/ |
| le-float-ieee-array: |
| #x95 #xB0 two-bytes ( four-bytes )^n |
| /where n is the value of the two-bytes production decoded |
| as an unsigned integer, 0 through 65535, decoded in |
| little-endian byte order/ |
| native-float-ieee-array: |
| #x95 ( #x31 | #xB1 ) two-bytes ( four-bytes )^n |
| /where n is the value of the two-bytes production decoded |
| as an unsigned integer, 0 through 65535, decoded in |
| the native byte order/ |
| ascii85-string: |
| "<~" (#x21..#x75 | "z" | psp-wsp )* "~>" |
| ascii85-homogeneous-number-array: |
| "<~" (#x21..#x75 | "z" | psp-wsp )* "~>" |
| one-byte: |
| #x0..#xFF |
| two-bytes: |
| #x0..#xFF #x0..#xFF |
| four-bytes: |
| #x0..#xFF #x0..#xFF #x0..#xFF #x0..#xFF |
| ps-wsp: |
| ps-wsp-chars |
| | ps-comment |
| ps-wsp-chars: |
| ( #x20 | #x9 | #xA | #xC | #xD | #x0 ) |
| ps-comment: |
| "%" ( #0..#9 | #xB..#xC | #xE..#xFF )* ( #xD | #xA ) |
| |
| This grammar is not technically a pure BNF because it uses binary |
| encoded data to encode how many characters should be as part of |
| several productions (short-binary-string, native-float-ieee-array, |
| etc.). |
| |
| The processing of the BNF must consume as much of a given BNF |
| production as possible, stopping at the point when a character |
| is encountered which no longer satisfies the production. |
| |
| The grammar allows the string to be empty (zero length). This |
| is not an error, instead specifies a path with no commands. |
| |
| Table 5.psCommands maps productions in the grammar above to the path |
| commands in Table 5.pathCommands; each such path command, with its |
| corresponding coordinates, is added to the path command sequence |
| of the path object. Each production listed in Table 5.svgCommands |
| consumes a quantity of values, matched by the "number" production, |
| consistent with the path command token's coordinate count listed |
| in Table 5.pathCommands. The "setbbox" and "ucache" products are |
| matched but do not result in path commands. |
| |
| Table 5.psCommands: PS Grammar Commands to Path Command Tokens |
| |
| Production Path command token |
| ------------ -------------------------- |
| arc CIRCULAR_CCW_ARC_TO_NV |
| arcn CIRCULAR_CW_ARC_TO_NV |
| arct CIRCULAR_TANGENT_ARC_TO_NV |
| ps-closepath CLOSE_PATH_NV |
| ps-curveto CUBIC_CURVE_TO_NV |
| ps-lineto LINE_TO_NV |
| ps-moveto MOVE_TO_NV |
| rcurveto RELATIVE_CUBIC_CURVE_TO_NV |
| rlineto RELATIVE_LINE_TO_NV |
| rmoveto RELATIVE_MOVE_TO_NV |
| setbbox - |
| ucache - |
| |
| The "number" production converts to a numeric coordinate value |
| in the obvious way. The "radix-number" production converts the |
| base-n integer conversion of its "base-number" production using |
| the base indicated by the base-10 integer conversion of its "base" |
| production where the base /n/ must be within the range 2 to 26. |
| The "base-number" is interpreted in base /n/; the "base-number" |
| production must contain digits ranging from 0 to /n/-1; digits greater |
| than 9 are represented by the letters A through Z (or a through z) |
| for the values 10 through 35 respectively. |
| |
| The "encoded-path" production provides a compact and precise way |
| to encode paths with the commands and coordinates decoupled. |
| |
| The "data-array" subproductions provide a sequence of coordinate |
| values for the encoded path's commands. The "data-array" |
| subproduction provides a sequence of numbers that is used by the |
| following "operator-string" production. |
| |
| The "operator-string" subproduction is interpreted as a sequence |
| of encoded path commands, one command per byte generated by |
| "operator-string"'s "binary-string" production. |
| |
| Each hexadecimal character in the "hexadecimal-binary-string" |
| production is a nibble (a 4-bit quantity). Each pair of characters |
| is two nibbles and they form a byte with the first nibble |
| representing the most signification bits of the byte. If the |
| "hexadecimal-binary-string" production contains an odd number of |
| hexadecimal characters, "0" is assumed to be suffixed to make an |
| even number of characters (so "A7C" would encode the bytes 167 for |
| "A7" followed by 192 for "C" which is treated as "C0" for 192). |
| Table 5.encodedPathOpcodes maps the values contained in the operator |
| string to path commands. Each command consumes from the coordinate |
| array supplied by the "data-array" production a number of values |
| for the command's coordinates equal to the path command token's |
| coordinate count listed in Table 5.pathCommands. If the value for |
| an element of the operator string is between 12 and 32 inclusive, |
| the grammar fails to parse at this point. If the value /n/ of an |
| element of the operator string is between 32 and 255, then this value |
| /n/-32 is treated as a repetition count and is treated as if /n/-32 |
| repetitions of the next command are contained in the operator string |
| instead and the appropriate number of coordinates are consumed from |
| the associated sequence of coordinate values. |
| |
| Table 5.encodedPathOpcodes |
| |
| Opcode Name |
| ------ --------- |
| 0 setbbox |
| 1 moveto |
| 2 rmoveto |
| 3 lineto |
| 4 rlineto |
| 5 curveto |
| 6 rcurveto |
| 7 arc |
| 8 arcn |
| 9 arct |
| 10 closepath |
| 11 ucache |
| |
| The ASCII characters in the "ascii85-binary-string" production |
| consists of a sequence of printable ASCII characters between the "<~" |
| and "~>" delimiters. This represents arbitrary binary data using |
| an encoding technique that products a 4:5 expansion as opposed to |
| the 1:2 expansion for the "hexadecimal-binary-string" production. |
| This encoding is known as ASCII base-85. |
| |
| Binary data in the ASCII base-85 encoding are encoded in 4-tuples |
| (groups of 4) each 4-tuple is used to produce a 5-type of ASCII |
| characters. If the binary 4-tuple is (b1,b2,b3,b4) and the encoded |
| 5-tuple is (c1,c2,c3,c4,c5), then the relation between them is: |
| |
| (b1 * 256^3) + (b2 * 256^2) + (b3 * 256^1) + b4 = |
| (c1 * 256^4) + (c2 * 256^3) + (c3 * 256^2) + (c4 * 256^3) + c5 |
| |
| The four bytes of binary data are interpreted as a base-256 number and |
| then converted into a base-85 number. The five "digits" of this number, |
| (c1,c2,c3,c4,c5), are then converted into ASCII characters by adding 33, |
| which is the ASCII code for '!', to each. ASCII characters in the |
| range '!' to 'u' are used, where '!' represented the value 0 and 'u' |
| represents the value 84. As a special case, if all five digits are |
| zero, they must be represented by either a single 'z' instead of by |
| '!!!!'. |
| |
| If the encoded sequence ends with a sequence of characters that is |
| not an even multiple of 4, the last 1, 2, or 3 characters to produce |
| a special final partial 5-tuple. Given n (1, 2, or 3) bytes of final |
| binary data, an encoder must first append 4-n zero bytes to make |
| a complete 4-tuple. Then, the encoder must encode the 4-tuple in |
| the usual way, but without applying the 'z' special case. Finally, |
| the encoder must write the first n+1 bytes of the resulting 5-tuple. |
| Those bytes are immediately followed by the "~>" terminal marker. |
| |
| This encoding scheme is reversible and the GL is responsible for |
| converting the ASCII base-85 string into its corresponding binary |
| data. White space within an ASCII base-85 encoded string is ignored. |
| |
| The following conditions constitute encoding violations of the ASCII |
| base-85 scheme: |
| |
| * The value represented by a 5-tuple is greater than 2^32-1 |
| |
| * The 'z' value occurs in the middle of a 5-tuple. |
| |
| * A final partial 5-tuple contains only one character. |
| |
| Any such encoding violation is a parsing error. |
| |
| Once the ASCII base-85 string is decoded, this sequence of bytes |
| is treated as operator elements in the identical manner as the |
| elements for the "hexadecimal-string" subproduction. This means |
| invalid opcodes are possible and are treated as parsing errors, and |
| Valid opcodes and counts consume coordinates from the "data-array" |
| production to generate path commands with associated coordinates. |
| |
| The "short-binary-string", "be-long-binary-string", and |
| "le-long-binary-string" subproductions of "operator-string" are |
| binary encodings of a sequence of operator string elements. |
| |
| The "short-binary-string" has a count from 0 to 255 supplied by its |
| "one-byte" subproduction which indicates how many bytes follow. |
| These remaining (unsigned) bytes generate the sequence of operator |
| string elements. |
| |
| The "be-long-binary-string" has a count from 0 to 65535 supplied by |
| its "two-byte" subproduction which indicates how many bytes follow. |
| These remaining (unsigned) bytes generate the sequence of operator |
| string elements. The "two-byte" subproduction is converted to a |
| count by multiplying the first unsigned byte by 256 and adding it |
| to the second unsigned byte. |
| |
| The "le-long-binary-string" has a count from 0 to 65535 supplied by |
| its "two-byte" subproduction which indicates how many bytes follow. |
| These remaining (unsigned) bytes generate the sequence of operator |
| string elements. The "two-byte" subproduction is converted to a |
| count by multiplying the second unsigned byte by 256 and adding it |
| to the first unsigned byte. |
| |
| The "encoded-path" fails to parse if invalid opcodes are detected |
| in the operator string or the sequence of numbers for coordinates |
| is exhausted prematurely. |
| |
| If the string fails to satisfy the ps-path production, the path |
| object named /path/ is not changed. The production may not be |
| satisfied for one of three reasons: the grammar cannot be not |
| satisfied by the string, the string has invalid sequences (such |
| as ASCII base-85 violations, exhausting the coordinate data in the |
| "data-array" production, or invalid opcodes encountered in the |
| "operator-string" production), or the grammar is satisfied but |
| there still remain a non-zero number of characters in the string. |
| None of these failures to satisfy the grammar generates an error; |
| instead the PATH_ERROR_POSITION_NV state is set to the character |
| offset where the grammar was first not satisfied, violated |
| semantically, or where the grammar was exhausted. If the string |
| was parsed successfully and the command did not generate an error, |
| the PATH_ERROR_POSITION_NV state is set to negative one to indicate |
| success. |
| |
| If a parsing error occurs, the exact value assigned to the |
| PATH_ERROR_POSITION_NV state variable is implementation-dependent |
| (because the specifics of error position determination is difficult |
| to specify) though the determined error location should be nearby |
| the first error. |
| |
| 5.X.1.3 Font Glyph Path Specification |
| |
| PATH GLYPHS FROM CHARACTER CODE SEQUENCE |
| |
| The command |
| |
| void PathGlyphsNV(uint firstPathName, |
| enum fontTarget, |
| const void *fontName, |
| bitfield fontStyle, |
| sizei numGlyphs, enum type, |
| const void *charcodes, |
| enum handleMissingGlyphs, |
| uint pathParameterTemplate, |
| float emScale); |
| |
| creates, if no error occurs, a range of path objects named from |
| /firstPathName/ to /firstPathName/+/numGlyphs/-1 based on the |
| font face indicated by /fontTarget/, /fontName/, and /fontStyle/ |
| and the sequence of /numGlyphs/ character codes listed in the |
| /charcodes/ array, as interpreted based by the /type/ parameter. |
| However each particular name in the range /firstPathName/ to |
| /firstPathName/+/numGlyphs/-1 is specified as a new path object only |
| if that name is not already in use as a path object; if a name is |
| already in use, that named path object is silently left undisturbed. |
| A path object name is also left undisturbed if the |
| /handleMissingGlyphs/ parameter is SKIP_MISSING_GLYPH_NV and the |
| character code for a given glyph corresponds to the font's missing |
| glyph or the character code is otherwise not available. |
| |
| The error INVALID_VALUE is generated if /numGlyphs/ or /emScale/ |
| is negative. |
| |
| The /fontTarget/ parameter must be one of STANDARD_FONT_NAME_NV, |
| SYSTEM_FONT_NAME_NV, or FILE_NAME_NV; otherwise the INVALID_ENUM |
| error is generated. |
| |
| The /handleMissingGlyphs/ parameter must be one of |
| SKIP_MISSING_GLYPH_NV or USE_MISSING_GLYPH_NV; otherwise the |
| INVALID_ENUM error is generated. |
| |
| If /fontTarget/ is STANDARD_FONT_NAME_NV, then /fontName/ is |
| interpreted as a nul-terminated 8-bit ASCII character string that |
| must be one of the following strings: "Serif", "Sans", "Mono", |
| or "Missing"; otherwise the INVALID_VALUE error is generated. |
| These "Serif", "Sans", and "Mono" names respectively correspond to |
| serif, sans-serif, and sans monospaced font faces with the intent |
| that the font face matches the appearance, metrics, and kerning |
| of the DejaVu fonts of the same names. All implementations /must/ |
| support these font names for the STANDARD_FONT_NAME_NV target. |
| |
| For the STANDARD_FONT_NAME_NV targets with "Serif", "Sans", and |
| "Mono", all implementations /must/ support the first 256 character |
| codes defined by Unicode and the ISO/IEC 8859-1 (Latin-1 Western |
| European) character encoding though implementations are strongly |
| encouraged to support as much of the Unicode character codes as the |
| system's underlying font and language support provides. |
| |
| For the STANDARD_FONT_NAME_NV targets with "Missing", the entire |
| sequence of path objects must be populated with an identical box |
| outline with metrics matching this box. |
| |
| If /fontTarget/ is SYSTEM_FONT_NAME_NV, then /fontName/ is interpreted |
| as a nul-terminated 8-bit ASCII character string that corresponds to a |
| system-specific font name. These names are intended to correspond to |
| the fonts names typically used in web content (e.g. Arial, Georgia, |
| Times Roman, Helvetica). The mapping of the system font character |
| string to a system font is assumed to be performed by the GL server. |
| |
| If /fontTarget/ is FILE_NAME_NV, then /fontName/ is interpreted as |
| a nul-terminated 8-bit ASCII character string that corresponds to |
| a system-specific file name in a standard outline font format. |
| The specific interpretation of this name depends on the system |
| conventions for identifying files by name. This name can be an |
| absolute or relative path. The name is expected to include the |
| font name's extension. The mapping of the font file name to a |
| font is assumed to be performed by the GL client. What font file |
| formats are supported is system dependent but implementations are |
| encouraged to support outline font formats standard to the system |
| (e.g. TrueType for Windows systems, etc.). |
| |
| If the /fontTarget/ and /fontName/ combination can not be loaded for |
| any reason (including the file name could not be opened, the font |
| name is not available on the system, the font file format is not |
| supported, the font file format is corrupted, etc.) and there is no |
| other error generated, the command succeeds silently (so no error |
| is generated) and the range of named path objects is not modified. |
| If the named path objects did not exist previously, they continue |
| to not exist. |
| |
| The /fontStyle/ parameter is a bitfield allowed to have the |
| bits BOLD_BIT_NV or ITALIC_BIT_NV set; if other bits are set, the |
| INVALID_VALUE error is generated. The font style is used as a hint to |
| indicate the style of the font face. Glyphs are generated with the |
| font's bold or italic style respectively (or combination thereof) |
| if the BOLD_BIT_NV or ITALIC_BIT_NV bits are set; otherwise, the |
| value 0 or NONE indicates the default font face style should be used |
| to generate the requested glyphs. In situations where the bold or |
| italic style of the font is encoded in the font name or file name, |
| the /fontStyle/ parameter is ignored. |
| |
| The generated glyphs for the path objects named /firstPathName/ |
| to /firstPathName/+/numGlyphs/-1 are specified by the /numGlyphs/ |
| character codes listed in the /charcodes/ array where each element of |
| the array is determined by the /type/ parameter that must be one of |
| UNSIGNED_BYTE, UNSIGNED_SHORT, UNSIGNED_INT, UTF8_NV, UTF16_NV, |
| 2_BYTES, 3_BYTES, and 4_BYTES with the array accessed in the same |
| manner as the CallLists command's /type/ and /lists/ parameters |
| (though not offset by the display list base), but indicating character |
| codes instead of display list names. |
| |
| The character codes from the /charcodes/ array are Unicode character |
| codes if the font in question can map from the Unicode character |
| set to the font's glyphs. If the font has no meaningful mapping |
| from Unicode, the font's standard character set is used instead |
| of Unicode (e.g. a font filled with non-standard symbols). For a |
| font supporting a character set that can be mapped to the Unicode |
| character set, a best effort should be made to map the specified |
| character code from its Unicode character code interpretation to |
| the closest appropriate glyph in the specified font. |
| |
| Path objects created from glyphs by PathGlyphsNV have their path |
| object metric state initialized from the metrics of the glyph from |
| which they were specified. Section 6.X.3. ("Path Object Glyph |
| Typographic Queries") explains how these metrics are queried and |
| what their values mean. While the per-glyph metrics are expected to |
| vary from glyph to glyph within a font face, the per-font metrics |
| are expected to be identical for every path object created from a |
| given font name and font style combination. |
| |
| Metrics in font space of glyphs are scaled by a value /s/ that is the |
| ratio of the /emScale/ parameter divided by the font's units per Em; |
| if the /emScale/ parameter equals zero, treat /emScale/ as if it was |
| identical to the font's units per Em such that /s/ is exactly 1.0. |
| Each glyph's outline are also scaled by /s/. The metric values /not/ |
| scaled by /s/ are GLYPH_HAS_KERNING_BIT_NV, FONT_UNITS_PER_EM_BIT_NV, |
| FONT_HAS_KERNING_BIT_NV, and FONT_NUM_GLYPH_INDICES_BIT_NV (since |
| these metric values are not specified in font units). |
| |
| The FONT_NUM_GLYPH_INDICES_BIT_NV metric value returns -1 for path |
| objects created with the STANDARD_FONT_NAME_NV (as such fonts are |
| not accessed by glyph index, only character point); otherwise, the |
| value is number of glyphs indices for the font, whether or not the |
| path object is created from a character point or glyph index. |
| |
| When unknown or missing character codes in a font face are specified |
| and the /handleMissingGlyph/ parameter is USE_MISSING_GLYPHS_NV, |
| this situation should be handled in a manner appropriate to the |
| character code, font face, and implementation. Typically this |
| involves using the font's missing glyph for the unknown or missing |
| character code. |
| |
| If the /pathParameterTemplate/ parameter names an existing path |
| object, that path object's current parameters listed in Table |
| 5.pathParameters (excepting PATH_FILL_MODE_NV as explained in |
| the following paragraph) are used to initialize the respective |
| parameters of path objects specified by this command; otherwise |
| if the /pathParameterTemplate/ path object name does not exist, |
| the initial path parameters are used as specified by table 6.Y |
| (without generating an error). |
| |
| Path objects created from glyphs by PathGlyphsNV have their |
| PATH_FILL_MODE_NV parameter, as explained in Section 5.X.1.5 ("Path |
| Parameter Specification"), initialized according to the fill |
| conventions of the font outlines within the font (instead of the |
| COUNT_UP_NV default for paths specified by means other than glyphs). |
| This may be one of: COUNT_UP_NV if the font's outline winding |
| convention is counterclockwise and its outline filling assumes the |
| non-zero winding rule; COUNT_DOWN_NV if the font's outline winding |
| convention is clockwise and its outline filling assumes the non-zero |
| winding rule; or INVERT if the font's outline filling assumes the |
| even-odd winding rule. |
| |
| PATH GLYPHS FROM CHARACTER CODE RANGE |
| |
| The command |
| |
| void PathGlyphRangeNV(uint firstPathName, |
| enum fontTarget, |
| const void *fontName, |
| bitfield fontStyle, |
| uint firstGlyph, |
| sizei numGlyphs, |
| enum handleMissingGlyphs, |
| uint pathParameterTemplate, |
| float emScale); |
| |
| allows a sequence of character codes in a font face to specify a |
| sequence of path objects and is equivalent to |
| |
| int *array = malloc(sizeof(int)*numGlyphs); |
| if (array) { |
| for (int i=0; i<numGlyphs; i++) { |
| array[i] = i + firstGlyph; |
| } |
| PathGlyphsNV(firstPathName, fontTarget, fontName, fontStyle, |
| numGlyphs, INT, array, |
| handleMissingGlyphs, pathParameterTemplate, emScale); |
| free(array); |
| } else { |
| // generate OUT_OF_MEMORY error |
| } |
| |
| PATH GLYPHS FROM GLYPH INDEX RANGE |
| |
| Advanced shaping of text renders glyphs by per-font glyph indices |
| (rather than Unicode code point). The commands |
| |
| enum PathGlyphIndexArrayNV(uint firstPathName, |
| enum fontTarget, |
| const void *fontName, |
| bitfield fontStyle, |
| uint firstGlyphIndex, |
| sizei numGlyphs, |
| uint pathParameterTemplate, |
| float emScale); |
| |
| enum PathMemoryGlyphIndexArrayNV(uint firstPathName, |
| enum fontTarget, |
| sizeiptr fontSize, |
| const void *fontData, |
| sizei faceIndex, |
| uint firstGlyphIndex, |
| sizei numGlyphs, |
| uint pathParameterTemplate, |
| float emScale); |
| |
| create, if successful and no error occurs, a range of path objects |
| that correspond to an array of glyphs as ordered by glyph index in |
| a font face. PathGlyphIndexArrayNV loads the font data from a file |
| name or system font name while PathMemoryGlyphIndexArrayNV loads |
| the font data from a standard font format in system memory. |
| |
| The commands return the value FONT_GLYPHS_AVAILABLE_NV when |
| successful; otherwise one of the following values is returned |
| depending on the nature of the failure. The unsuccessful command |
| returns the value FONT_TARGET_UNAVAILABLE_NV if the implementation |
| does not support a valid /fontTarget/, FONT_UNAVAILABLE_NV if |
| the font is not available (e.g. does not exist on the system), or |
| FONT_UNINTELLIGIBLE_NV if the font is available but cannot be loaded |
| for some implementation-dependent reason. FONT_UNAVAILABLE_NV will |
| not be returned by PathMemoryGlyphIndexArrayNV because the font |
| data is read from system memory. If the command generates an error, |
| that error's enum value will be returned. For example, an invalid |
| value for /fontTarget/ will return INVALID_ENUM. While the return |
| value indicates the error, the error will /also/ be generated in the |
| conventional way so GetError will return it and error callbacks are |
| generated normally. |
| |
| When successful, path names /firstPathName/ through |
| /firstPathName+numGlyphs-1/ now are specified as path objects |
| corresponding to the sequence of glyphs in the font indicated |
| by /fontTarget/, /fontSize/, and /fontData/ for glyph indices |
| from /firstGlyphIndex/ to /firstGlyphIndex+numGlyphs-1/ where |
| /firstPathName/ corresponds to the glyph index /firstGlyphIndex/ |
| and onward sequentially. If a glyph index does not correspond to an |
| actual glyph index in the font format, the respective path object is |
| left undisturbed. (It is the application's responsibility to know |
| the valid range of glyph indices for the font.) When unsuccessful |
| other than due to an OUT_OF_MEMORY error, no path objects are |
| specified or otherwise modified. |
| |
| The path objects are created in the same manner described for |
| PathGlyphsNV in section 5.X.1.3 (Font Glyph Path Specification) |
| except the GLYPH_HAS_KERNING_BIT_NV and FONT_HAS_KERNING_BIT_NV |
| metrics are always false (because GetPathSpacingNV applies to |
| glyphs specified from Unicode code points). In particular, the |
| /pathParameterTemplate/ and /emScale/ parameters have the same |
| interpretation as the PathGlyphsNV command. |
| |
| For the PathGlyphIndexArrayNV command, the /fontTarget/ parameter |
| must be either SYSTEM_FONT_NAME_NV or FILE_NAME_NV; otherwise the |
| INVALID_ENUM error is generated. The /fontStyle/ parameter is |
| a bitfield allowed to have the bits BOLD_BIT_NV or ITALIC_BIT_NV |
| set; if other bits are set, the INVALID_VALUE error is generated. |
| The interpretation of the /fontTarget/, /fontName/, and /fontStyle/ |
| parameters is identical to the interpretation described in section |
| 5.X.1.3 (Font Glyph Path Specification). |
| |
| For the PathMemoryGlyphIndexArrayNV command, /fontTarget/ must |
| be STANDARD_FONT_FORMAT_NV; otherwise INVALID_ENUM is generated |
| (and returned). STANDARD_FONT_FORMAT_NV implies: /fontSize/ is |
| the size of the memory storing the font data in memory; /fontData/ |
| is a pointer to the beginning of the font data; and /faceIndex/ is |
| the index of the face within the font, typically specified as zero. |
| |
| The specific standard font formats supported by |
| STANDARD_FONT_FORMAT_NV are implementation-dependent, but the TrueType |
| format should be supported. Magic numbers if the font memory data |
| are expected to be used to identify the specific font format. |
| |
| The INVALID_VALUE error is generated if any of /fontSize/ or |
| /faceIndex/ or /emScale/ are negative. |
| |
| [NOTE: PathGlyphIndexRangeNV is deprecated in favor of |
| PathGlyphIndexArrayNV and PathMemoryGlyphIndexArrayNV.] |
| |
| The command |
| |
| enum PathGlyphIndexRangeNV(enum fontTarget, |
| const void *fontName, |
| bitfield fontStyle, |
| uint pathParameterTemplate, |
| float emScale, |
| uint baseAndCount[2]); |
| |
| creates, if successful and no error occurs, a range of path objects |
| that correspond to the complete range of glyphs as ordered by glyph |
| index in a font face. |
| |
| The command returns the value FONT_GLYPHS_AVAILABLE_NV when |
| successful; otherwise one of the following values is returned |
| depending on the nature of the failure. The unsuccessful command |
| returns the value FONT_TARGET_UNAVAILABLE_NV if the implementation |
| does not support a valid /fontTarget/, FONT_UNAVAILABLE_NV if |
| the font is not available (e.g. does not exist on the system), or |
| FONT_UNINTELLIGIBLE_NV if the font is available but cannot be loaded |
| for some implementation-dependent reason. If the command generates |
| an error, that error's enum value will be returned. For example, an |
| invalid value for /fontTarget/ will return INVALID_ENUM. While the |
| return value indicates the error, the error will /also/ be generated |
| in the conventional way so GetError will return it and error callbacks |
| are generated normally. |
| |
| The /fontTarget/ parameter must be either SYSTEM_FONT_NAME_NV |
| or FILE_NAME_NV; otherwise the INVALID_ENUM error is generated. |
| The interpretation of the /fontTarget/ and /fontName/ parameters |
| is identical to the interpretation described in section 5.X.1.3 |
| (Font Glyph Path Specification). |
| |
| The error INVALID_VALUE is generated if /emScale/ is negative. |
| |
| The /fontStyle/ parameter is a bitfield allowed to have the |
| bits BOLD_BIT_NV or ITALIC_BIT_NV set; if other bits are set, the |
| INVALID_VALUE error is generated. |
| |
| When successful, elements 0 and 1 of the /baseAndCount/ array |
| parameter are written values /B/ and /N/ respectively where the |
| path names /B/ through /B+N-1/ are previously unused (i.e. there |
| are /N/ previously unused path object names starting at /B/) but |
| now are specified as path objects corresponding to the complete set |
| of glyphs in the font indicated by /fontTarget/ and /fontName/. |
| When unsuccessful (including when any error, even OUT_OF_MEMORY, |
| is generated by the command), elements 0 and 1 of the /baseAndCount/ |
| array parameter are both written to zero. |
| |
| The path objects are created in the same manner described for |
| PathGlyphsNV in section 5.X.1.3 (Font Glyph Path Specification) |
| except the GLYPH_HAS_KERNING_BIT_NV and FONT_HAS_KERNING_BIT_NV |
| metrics are always false (because GetPathSpacingNV applies to |
| glyphs specified from Unicode code points). In particular, the |
| /pathParameterTemplate/ and /emScale/ parameters have the same |
| interpretation as the PathGlyphsNV command. |
| |
| 5.X.1.4 Path Modification |
| |
| Several commands allow the commands and/or coordinates of an existing |
| path object to be modified. |
| |
| The command |
| |
| void PathCoordsNV(uint path, |
| sizei numCoords, enum coordType, |
| const void *coords); |
| |
| replaces all the coordinates of an existing path object with a new |
| set of coordinates. /path/ names the path object to modify; the |
| error INVALID_OPERATION is generated if /path/ is not an existing |
| path object. |
| |
| The new path coordinates are read sequentially from the |
| /coords/ array. The type of the coordinates read from the /coords/ |
| array is determined by the /coordType/ parameter which must be |
| one of BYTE, UNSIGNED_BYTE, SHORT, UNSIGNED_SHORT, or FLOAT, |
| otherwise the INVALID_ENUM error is generated. |
| |
| The INVALID_OPERATION error is generated if /numCoords/ does not |
| equal the number of coordinates referenced by the path object's |
| existing command sequence (so /numCoords/ provides a sanity check |
| that the /coords/ array is being interpreted properly). The error |
| INVALID_VALUE is generated if /numCoords/ is negative. |
| |
| If the PathCoordsNV command results in an error, the path object named |
| /path/ is not changed; if there is no error, the prior coordinates of |
| /path/ are lost. If there is no error, the commands and parameters |
| of the path object are not changed. |
| |
| The command |
| |
| void PathSubCoordsNV(uint path, |
| sizei coordStart, |
| sizei numCoords, enum coordType, |
| const void *coords); |
| |
| replaces a range of the coordinates of an existing path object with |
| a new set of coordinates. /path/ names the path object to modify; |
| the error INVALID_OPERATION is generated if /path/ is not an existing |
| path object. |
| |
| The new path coordinates are read sequentially from the |
| /coords/ array. The type of the coordinates read from the /coords/ |
| array is determined by the /coordType/ parameter which must be |
| one of BYTE, UNSIGNED_BYTE, SHORT, UNSIGNED_SHORT, or FLOAT, |
| otherwise the INVALID_ENUM error is generated. |
| |
| The coordinates from the /coords/ array replace the coordinates |
| starting at coordinate index (zero-based) /coordStart/ through |
| /coordStart/+/numCoords/-1 inclusive in the existing path object's |
| coordinate array. If /numCoords/ is zero, no coordinates are changed. |
| If /coordStart/+/numCoords/ is greater than the number of coordinates |
| in the existing path object, the INVALID_OPERATION error is generated. |
| If either /coordStart/ or /numCoords/ is negative, the INVALID_VALUE |
| error is generated. |
| |
| If the PathCoordsNV command results in an error, the path object named |
| /path/ is not changed; if there is no error, the prior coordinates |
| within the updated range of /path/ are lost. If there is no error, |
| the commands, coordinates outside the updated range, and parameters |
| of the path object are not changed. |
| |
| The command |
| |
| void PathSubCommandsNV(uint path, |
| sizei commandStart, sizei commandsToDelete, |
| sizei numCommands, const ubyte *commands, |
| sizei numCoords, enum coordType, |
| const void *coords); |
| |
| replaces a range of existing commands and their associated coordinates |
| with a new sequence of commands and associated coordinates. /path/ |
| names the path object to modify; the error INVALID_OPERATION is |
| generated if /path/ is not an existing path object. |
| |
| The error INVALID_OPERATION is generated if any of /commandStart/, |
| /commandsToDelete/, /numCommands/, or /numCoords/ is negative. |
| |
| The PathSubCommandsNV command works in two steps. |
| First, deleting commands in the range /commandStart/ to |
| /commandStart/+/commandsToDelete/-1 inclusive from the existing |
| path object. If /commandsToDelete/ exceeds the number of commands |
| from /commandStart/ to the end of the path command sequence, |
| all the commands from /commandsToDelete/ on are deleted. This |
| includes deleting the coordinates associated with these commands. |
| If /commandsToDelete/ is zero, zero commands and zero coordinates are |
| deleted. Second, /numCommands/ read sequentially from the /commands/ |
| array are inserted into the existing path object immediately before |
| index /commandStart/. This includes inserting a corresponding number |
| of coordinates from the /coords/ array. If the index /commandStart/ |
| is greater than the largest valid command index of the path object, |
| the commands are simply appended to the end of the path objects |
| command and coordinate sequences. |
| |
| Each of the /numCommands/ commands in the /command/ array references |
| a number of coordinates specified by "Coordinate count" column of |
| Table 5.pathCommands, starting with the first (zero) element of |
| the /coords/ array and advancing by the coordinate count for each |
| command. If any of these /numCommands/ commands are not listed |
| in the "Token" or "Character aliases" columns of Table 5.pathCommands, |
| the INVALID_ENUM error is generated. |
| |
| The INVALID_OPERATION error is generated if /numCoords/ does not equal |
| the number of coordinates referenced by the command sequence to insert |
| as specified by /numCommands/ and /commands/ (so /numCoords/ provides |
| a sanity check that the /coords/ array is being interpreted properly). |
| The error INVALID_VALUE is generated if any of /commandStart/, |
| /commandsToDelete/, /numCommands/ or /numCoords/ are negative. |
| |
| The type of the coordinates in the /coords/ array is specified |
| by /coordType/ and must be one of BYTE, UNSIGNED_BYTE, SHORT, |
| UNSIGNED_SHORT, or FLOAT; otherwise the INVALID_ENUM error is |
| generated. |
| |
| If the PathSubCommandsNV command results in an error, the path |
| object named /path/ is not changed; if there is no error, the prior |
| (now deleted) commands and coordinates within the updated range of |
| /path/ are lost. If there is no error, the commands, coordinates |
| outside the deleted range, and parameters of the path object are not |
| changed though commands and coordinates indexed beyond /commandStart/ |
| are shifted in their sequence within the path object to make room |
| in the command and coordinate arrays for the newly inserted commands |
| and coordinates. |
| |
| 5.X.1.5 Path Parameter Specification |
| |
| Each path object has its own set of path parameters that control |
| how the path object is filled and stroked when stenciled and covered. |
| |
| Table 5.pathParameters |
| |
| Name Type Required Values or Range |
| ------------------------------- ------- ----------------------------------------------- |
| PATH_STROKE_WIDTH_NV float non-negative |
| PATH_INITIAL_END_CAP_NV enum FLAT, SQUARE_NV, ROUND_NV, TRIANGULAR_NV |
| PATH_TERMINAL_END_CAP_NV enum FLAT, SQUARE_NV, ROUND_NV, TRIANGULAR_NV |
| PATH_INITIAL_DASH_CAP_NV enum FLAT, SQUARE_NV, ROUND_NV, TRIANGULAR_NV |
| PATH_TERMINAL_DASH_CAP_NV enum FLAT, SQUARE_NV, ROUND_NV, TRIANGULAR_NV |
| PATH_JOIN_STYLE_NV enum MITER_REVERT_NV, MITER_TRUNCATE_NV, BEVEL_NV, ROUND_NV, NONE |
| PATH_MITER_LIMIT_NV float non-negative |
| PATH_DASH_OFFSET_NV float any value |
| PATH_DASH_OFFSET_RESET_NV enum MOVE_TO_RESET_NV, MOVE_TO_CONTINUES_NV |
| PATH_CLIENT_LENGTH_NV float non-negative |
| PATH_FILL_MODE_NV enum COUNT_UP_NV, COUNT_DOWN_NV, INVERT |
| PATH_FILL_MASK_NV integer any value |
| PATH_FILL_COVER_MODE_NV enum CONVEX_HULL_NV, BOUNDING_BOX_NV |
| PATH_STROKE_COVER_MODE_NV enum CONVEX_HULL_NV, BOUNDING_BOX_NV |
| PATH_STROKE_MASK_NV integer any value |
| PATH_STROKE_BOUND_NV float any value in [0.0,1.0] |
| |
| The commands |
| |
| void PathParameterivNV(uint path, enum pname, const int *value); |
| void PathParameteriNV(uint path, enum pname, int value); |
| void PathParameterfvNV(uint path, enum pname, const float *value); |
| void PathParameterfNV(uint path, enum pname, float value); |
| |
| specify the value of path parameters for the specified path object |
| named /path/. The error INVALID_OPERATION is generated if /path/ |
| is not an existing path object. |
| |
| Each parameter has a single (scalar) value. |
| |
| /pname/ must be one of the tokens in the "Name" column of |
| Table 5.pathParameters, PATH_END_CAPS_NV, or PATH_DASH_CAPS_NV. |
| The required values or range of each allowed parameter name token |
| is listed in Table 5.pathParameter's "Required Values/Range" column. |
| |
| For values of /pname/ listed in Table 5.pathsParameters, the specified |
| parameter is specified by /value/ when /value/ is a float or int, |
| or if /value/ is a pointer to a float or int, accessed through that |
| pointer. The error INVALID_VALUE is generated if the specified |
| value is negative for parameters required to be non-negative in |
| Table 5.pathParameters. Values specified to be clamped to the [0,1] range |
| in Table 5.pathParameters are so clamped prior to setting the |
| specified path parameter to that clamped value. |
| |
| The /pname/ of PATH_END_CAPS_NV is handled specially and updates |
| /both/ the PATH_INITIAL_END_CAP_NV and PATH_TERMINAL_END_CAP_NV |
| parameters of the path with the specified value. The /pname/ |
| of PATH_DASH_CAPS_NV is handled specially and updates /both/ the |
| PATH_INITIAL_DASH_CAP_NV and PATH_TERMINAL_DASH_CAP_NV parameters |
| of the path with the specified value. |
| |
| The error INVALID_VALUE is generated if the specified parameter value |
| is not within the require range for parameters typed float or integer. |
| The error INVALID_ENUM is generated if the specified parameter value |
| is not one of the listed tokens for parameters typed enum. |
| |
| The dash pattern of a path object consists of a sequence of path-space |
| lengths of alternating "on" and "off" dash segments. The first |
| value of the dash array defines the length, in path space, of the |
| first "on" dash segment. The second value defines the length of the |
| following "off" segment. Each subsequent pair of values defines one |
| "on" and one "off" segment. |
| |
| Parameters to control the dash pattern of a stroked path are specified |
| by the command |
| |
| void PathDashArrayNV(uint path, |
| sizei dashCount, const float *dashArray); |
| |
| where /path/ is the name of an existing path object. The error |
| INVALID_OPERATION is generated if /path/ is not an existing path |
| object. |
| |
| A /dashCount/ of zero indicates the path object is not dashed; in |
| this case, the /dashArray/ is not accessed. Otherwise, /dashCount/ |
| provides a count of how many float values to read from the /dashArray/ |
| array. If any of the /dashCount/ elements of /dashArray/ are |
| negative, the INVALID_VALUE error is generated. |
| |
| If /dashCount/ is negative, the INVALID_VALUE error is generated. |
| |
| If an error occurs, the path object's existing dash pattern state |
| is not changed. |
| |
| The path parameters of a newly specified path object are initialized |
| as specified in Table 6.Y. |
| |
| 5.X.1.6 Path Weighting, Interpolation, and Copying |
| |
| The command |
| |
| void WeightPathsNV(uint resultPath, |
| sizei numPaths, |
| const uint paths[], const float weights[]); |
| |
| linearly combines, as appropriate, the /numPaths/ path objects in |
| the array paths based on each path object's respective weight from |
| the weights array. The resulting path creates or replaces the |
| path object /resultPath/. The INVALID_VALUE error is generated if |
| /numPaths/ is less than one. |
| |
| If the /resultPath/ name also names one of the paths in the /paths/ |
| array, the path resulting from the linear combination of paths |
| replaces the source path also named /resultPath/ but not until after |
| the linear combination path has been determined. |
| |
| This command requires all the paths in the paths array to |
| be /consistent/; otherwise the INVALID_OPERATION error is |
| generated. For all the paths to be /consistent/, all /numPaths/ paths |
| in the /paths/ array must have the identical count of commands and |
| each corresponding /i/th command in each path must have the identical |
| command type. |
| |
| However the arc commands (specifically SMALL_CCW_ARC_TO_NV, |
| RELATIVE_SMALL_CCW_ARC_TO_NV, SMALL_CW_ARC_TO_NV, |
| RELATIVE_SMALL_CW_ARC_TO_NV, LARGE_CCW_ARC_TO_NV, |
| RELATIVE_LARGE_CCW_ARC_TO_NV, LARGE_CW_ARC_TO_NV, |
| RELATIVE_LARGE_CW_ARC_TO_NV, CIRCULAR_CCW_ARC_TO_NV, |
| CIRCULAR_CW_ARC_TO_NV, CIRCULAR_TANGENT_ARC_TO_NV, ARC_TO_NV, and |
| RELATIVE_ARC_TO_NV) can not be weighted because the linear combination |
| of the curves these arc commands generate do not generally result in |
| a command of the same form; so if any of these arc commands appears |
| in a path object passed to WeightPathsNV the INVALID_OPERATION error |
| is generated. |
| |
| The weighted path has a command sequence identical to any of the |
| input path objects to be weighted (since all the input path command |
| sequences are required to be identical). |
| |
| The weighted path has a coordinate sequence constructed by weighting |
| each correspondingly indexed coordinate /i/ for all paths indexed by |
| /j/ from zero to /numPaths/-1 in the /paths/ array. Each coordinate |
| /i/ from path /j/ is weighted by the weight in /weights/ indexed |
| by /j/. |
| |
| The path parameters for the weighted path are copied from the path |
| named by the first (0th) element of the /paths/ array. The path |
| metric values (as queried by GetPathMetricsNV in section 6.X.3) |
| are all specified to be -1 for the newly specified path object |
| (ignoring the path metrics for all the input path objects). |
| Kerning information (as queriable by GetPathSpacingNV in section |
| 6.X.3) is also not copied. |
| |
| The command |
| |
| void InterpolatePathsNV(uint resultPath, |
| uint pathA, uint pathB, |
| float weight); |
| |
| is equivalent to |
| |
| uint paths[2] = { pathA, pathB }; |
| float weights[2] = { 1-weight, weight }; |
| WeightPathsNV(resultPath, 2, paths, weights); |
| |
| The command |
| |
| void CopyPathNV(uint resultPath, uint srcPath); |
| |
| copies the path object named /srcPath/ to the path object named |
| /resultPath/. The error INVALID_OPERATION is generated if /srcPath/ |
| does not exist. The outline (commands and coordinates), parameters, |
| and glyph metrics and kerning information (if they exist) are all |
| copied without change. |
| |
| 5.X.1.7 Path Transformation |
| |
| The command |
| |
| void TransformPathNV(uint resultPath, |
| uint srcPath, |
| enum transformType, |
| const float *transformValues); |
| |
| transforms the path object named /srcPath/ by the transform specified |
| by the /transformType/ and its associated /transformValues/. |
| The resulting path creates or replaces the path object /resultPath/. |
| |
| If the /resultPath/ and /srcPath/ names are identical, the path resulting |
| from the transform replaces the name after the source path is transformed. |
| |
| The /transformType/ must be one of NONE, TRANSLATE_X_NV, |
| TRANSLATE_Y_NV, TRANSLATE_2D_NV, TRANSLATE_3D_NV, AFFINE_2D_NV, |
| AFFINE_3D_NV, TRANSPOSE_AFFINE_2D_NV, or TRANSPOSE_AFFINE_3D_NV. |
| |
| transformType Matrix |
| -------------------------- ------------------------- |
| NONE [ 1 0 0 0 ] |
| [ 0 1 0 0 ] |
| [ 0 0 1 0 ] |
| [ 0 0 0 1 ] |
| |
| TRANSLATE_X_NV [ 1 0 0 v0 ] |
| [ 0 1 0 0 ] |
| [ 0 0 1 0 ] |
| [ 0 0 0 1 ] |
| |
| TRANSLATE_Y_NV [ 1 0 0 0 ] |
| [ 0 1 0 v0 ] |
| [ 0 0 1 0 ] |
| [ 0 0 0 1 ] |
| |
| TRANSLATE_2D_NV [ 1 0 0 v0 ] |
| [ 0 1 0 v1 ] |
| [ 0 0 1 0 ] |
| [ 0 0 0 1 ] |
| |
| TRANSLATE_3D_NV [ 1 0 0 v0 ] |
| [ 0 1 0 v1 ] |
| [ 0 0 1 v2 ] |
| [ 0 0 0 1 ] |
| |
| AFFINE_2D_NV [ v0 v2 0 v4 ] |
| [ v1 v3 0 v5 ] |
| [ 0 0 1 0 ] |
| [ 0 0 0 1 ] |
| |
| TRANSPOSE_AFFINE_2D_NV [ v0 v1 0 v2 ] |
| [ v3 v4 0 v5 ] |
| [ 0 0 1 0 ] |
| [ 0 0 0 1 ] |
| |
| AFFINE_3D_NV [ v0 v3 v6 v9 ] |
| [ v1 v4 v7 v10 ] |
| [ v2 v5 v8 v11 ] |
| [ 0 0 0 1 ] |
| |
| TRANSPOSE_AFFINE_3D_NV [ v0 v1 v2 v3 ] |
| [ v4 v5 v6 v7 ] |
| [ v8 v9 v10 v11 ] |
| [ 0 0 0 1 ] |
| |
| Table 5.transformType: Mapping from /transformType/ to a 4x4 |
| transform matrix where v/i/ is the ith (base 0) element of the |
| /transformValues/ array. |
| |
| The transformation of a path proceeds path command by path command. |
| Each path command results in a transformed path command equivalent |
| to what would happen if every point on the path command segment were |
| transformed by the transform from Table 5.transformType and had a |
| projective normalization applied. |
| |
| Commands with absolute control points have their control points |
| transformed by the effective 4x4 projective matrix, and the resulting |
| x & y coordinates serve as the transformed command's respective |
| control point. |
| |
| Control points of relative commands are first made into absolute |
| coordinates given the command's current control point, transformed |
| in the same manner as an absolute control point, and then adjusted |
| back to relative to their transformed current control point. |
| |
| Horizontal and vertical line to commands are promoted to corresponding |
| "line to" commands if the transformed command is not an exactly |
| horizontal or vertical command respectively after transformation; |
| otherwise, these commands are not promoted but may transition from |
| horizontal to vertical or vice versa as the case may be. |
| |
| Commands for partial elliptical arcs generate an equivalent new |
| transformed arc. |
| |
| XXX more detail/math about arcs? |
| |
| The CIRCULAR_CCW_ARC_TO_NV and CIRCULAR_CW_ARC_TO_NV commands are |
| converted to transformed *_ARC_TO_NV commands if the transformed |
| circular arc is itself not a circular arc. |
| |
| The CIRCULAR_TANGENT_ARC_TO_NV command is converted into a LINE_TO_NV |
| command and *_ARC_TO_NV command if the transformed circular arc is |
| itself not a circular arc. |
| |
| The CLOSE_PATH_NV and RESTART_PATH_NV (having no control points) |
| are undisturbed by path transformation. The order of path commands |
| is invariant under path transformation. |
| |
| 5.X.1.8 Path Name Management |
| |
| The command |
| |
| uint GenPathsNV(sizei range); |
| |
| returns an integer /n/ such that names /n/, ..., /n+range-1/ are |
| previously unused (i.e. there are /range/ previously unused path object |
| names starting at /n/). These names are marked as used, for the |
| purposes of subsequent GenPathsNV only, but they do not acquire |
| path object state until each particular name is used to specify |
| a path object. |
| |
| Path objects are deleted by calling |
| |
| void DeletePathsNV(uint path, sizei range); |
| |
| where /path/ contains /range/ names of path objects to be delete. |
| After a path object is deleted, its name is again unused. Unused |
| names in /paths/ are silently ignored. |
| |
| The query |
| |
| boolean IsPathNV(uint path); |
| |
| returns TRUE if /path/ is the name of a path object. If path is |
| not the name of a path object, or if an error condition occurs, |
| IsPathNV returns FALSE. A name retuned by GenPathsNV, but without |
| a path specified for it yet, is not the name of a path object. |
| |
| 5.X.2 Path Rendering |
| |
| Path objects update the framebuffer through one of two processes: |
| "stenciling" that updates /just/ the stencil buffer with the path's |
| coverage information, and "covering" that rasterizes fragments into |
| the framebuffer for a region guaranteed to cover the region of path |
| coverage updated by stenciling, assuming the same path object, |
| fill mode or stroking parameters, transformation state, and set of |
| accessible samples (as will be explained). |
| |
| 5.X.2.1 Path Stenciling |
| |
| STENCILING FILLED PATHS |
| |
| The command |
| |
| void PathStencilFuncNV(enum func, int ref, uint mask); |
| |
| configures the stencil function, stencil reference value, and stencil |
| read mask to be used by the StencilFillPathNV and StencilStrokePathNV |
| commands described subsequently. The parameters accept the same |
| values allowed by the StencilFunc command. |
| |
| The command |
| |
| void PathStencilDepthOffsetNV(float factor, float units); |
| |
| configures the depth offset factor and units state (see section 3.6.4) |
| to be used by the StencilFillPathNV and StencilStrokePathNV commands |
| described subsequently. |
| |
| The command |
| |
| void StencilFillPathNV(uint path, |
| enum fillMode, uint mask); |
| |
| transforms into window space the outline of the path object named |
| /path/ based on the current modelview, projection, viewport, |
| and depth range transforms (ignoring any vertex and/or geometry |
| shader or program that might be active/enabled) and then updates |
| the stencil values of all /accessible samples/ (explained below) in |
| the framebuffer. Each sample's stencil buffer value is updated based |
| on the winding number of that sample with respect to the transformed |
| outline of the path object with any non-closed subpath forced closed |
| and the specified /fillMode/. |
| |
| If /path/ does not name an existing path object, the command does |
| nothing (and no error is generated). |
| |
| If the path's command sequence specifies unclosed subpaths (so not |
| contours) due to MOVE_TO_NV commands, such subpaths are trivially |
| closed by connecting with a line segment the initial and terminal |
| control points of each such path command subsequence. |
| |
| Transformation of a path's outline works by taking all positions |
| on the path's outline in 2D path space (x,y) and constructing an |
| object space position (x,y,0,1) that is then used as the (xo,yo,zo,wo) |
| position in section 2.12 ("Fixed-Function Vertex Transformation") |
| to compute corresponding eye-space coordinates (xe,ye,ze,we) and |
| clip-space coordinates (xc,yc,zc,wc). A path outline's clip-space |
| coordinates are further transformed into window space as described in |
| section 2.16 ("Coordinate Transformations"). This process provides a |
| mapping 2D path coordinates to 2D window coordinates and depth values. |
| The resulting 2D window coordinates are undefined if any of the |
| transformations involved are singular or may be inaccurate if any |
| of the transformations (or their combination) are ill-conditioned. |
| |
| The winding number for a sample with respect to the path outline, |
| transformed into window space, is computed by counting the (signed) |
| number of revolutions around the sample point when traversing each |
| (trivially closed if necessary) contour once in the transformed path. |
| This traversal is performed in the order of the path's command |
| sequence. Starting from an initially zero winding count, each |
| counterclockwise revolution when the front face mode is CCW (or |
| clockwise revolution when the front face mode is CW) around the sample |
| point increments the winding count by one; while each clockwise |
| revolution when the front face mode is CCW (or counterclockwise |
| revolution when the front face mode is CW) around the sample point |
| decrements the winding count by one. |
| |
| The /mask/ parameter controls what subset of stencil bits are affected |
| by the command. If the /mask/ parameter is zero, the path object's |
| fill mask parameter (PATH_FILL_MASK_NV) is considered the effective |
| value of /mask/. |
| |
| The /fillMode/ parameter must be one of INVERT, COUNT_UP_NV, |
| COUNT_DOWN_NV, or PATH_FILL_MODE_NV; otherwise the INVALID_ENUM error |
| is generated. INVERT inverts the bits set in the effective /mask/ |
| value for each sample's stencil value if the winding number for the |
| given sample is odd. COUNT_UP_NV adds with modulo n arithmetic the |
| winding number of each sample with the sample's prior stencil buffer |
| value; the result of this addition is written into the sample's |
| stencil value but the bits of the stencil value not set in the |
| effective /mask/ value are left unchanged. COUNT_DOWN_NV subtracts |
| with modulo /n/ arithmetic the winding number of each sample with the |
| sample's prior stencil buffer value; the result of this subtraction is |
| written into the sample's stencil value but the bits of the stencil |
| value not set in the effective /mask/ value are left unchanged. |
| PATH_FILL_MODE_NV uses the path object's counting mode parameter |
| (one of INVERT, COUNT_UP_NV, or COUNT_DOWN_NV). |
| |
| The value of /n/ for the modulo /n/ arithmetic used by COUNT_UP_NV |
| and COUNT_DOWN_NV is the effective /mask/+1. The error INVALID_VALUE |
| is generated if the specified /fillMode/ is COUNT_UP_NV or |
| COUNT_DOWN_NV and the specified /mask/+1 is not an integer power |
| of two. If the /fillMode/ is PATH_FILL_MODE_NV; the path object's |
| counting mode parameter is COUNT_UP_NV or COUNT_DOWN_NV; and the |
| effective mask+1 value is not an integer power of two, treat the |
| mask as zero (effectively meaning no stencil bits will be modified). |
| |
| ACCESSIBLE SAMPLES WITH RESPECT TO A TRANSFORMED PATH |
| |
| The accessible samples of a transformed path that are updated are |
| the samples that remain after discarding the following samples: |
| |
| * Any sample that would be clipped as specified in section 2.22 |
| ("Primitive Clipping") because its corresponding position in |
| clip space (xc,yc,zc,wc) or (xe,ye,ze,we) would be clipped |
| by the clip volume or enabled client-defined clip planes. |
| |
| * Any sample that would not be updated during polygon rendering |
| due to polygon stipple (section 3.6.2) if POLYGON_STIPPLE |
| is enabled. |
| |
| * Any sample that would fail the pixel ownership test (section |
| 4.1.1) if rasterized. |
| |
| * Any sample that would fail the scissor test (section 4.1.2) |
| if SCISSOR_TEST is enabled. |
| |
| * Any sample that would fail the depth test (section 4.1.6) |
| if DEPTH_TEST is enabled where the fragment depth for the |
| depth test comes from the depth plane of the path when |
| transformed by the modelview, projection, viewport, and |
| depth range transforms and depth offset (section 3.6.4) |
| has been applied based on the slope of this plane operating |
| as if POLYGON_OFFSET_FILL is forced enabled and using the |
| factor and units parameters set by PathStencilDepthOffsetNV |
| (rather than the state set by PolygonOffset). |
| |
| * Any sample that would fail the depth bounds test (section |
| 4.1.X in EXT_depth_bounds_test specification) if |
| DEPTH_BOUNDS_TEST_EXT is enabled. |
| |
| And for the StencilFillPathNV and StencilStrokePathNV commands (so |
| not applicable to the CoverFillPathNV and CoverStrokePathNV commands): |
| |
| * Any sample that would fail the (implicitly enabled) stencil |
| test (section 4.1.5) with the stencil function configured |
| based on the path stencil function state configured by |
| PathStencilFuncNV. In the case of the StencilFillPathNV |
| and StencilStrokePathNV commands and their instanced |
| versions (section 5.X.2.3), the effective stencil read |
| mask for the stencil mask is treated as the value of |
| PATH_STENCIL_VALUE_MASK bit-wise ANDed with the bit-invert |
| of the effective /mask/ parameter value; otherwise, for the |
| cover commands, the stencil test operates normally. In the |
| case the stencil test fails during a path stencil operation, |
| the stencil fail operation is ignored and the pixel's stencil |
| value is left undisturbed (as if the stencil operation was |
| KEEP). |
| |
| * The state of the face culling (CULL_FACE) enable is ignored. |
| |
| STENCILING STROKED PATHS |
| |
| The command |
| |
| void StencilStrokePathNV(uint path, |
| int reference, uint mask); |
| |
| transforms into window space the stroked region of the path object |
| named /path/ based on the current modelview, projection, viewport, |
| and depth range transforms (ignoring any vertex and/or geometry |
| shader or program that might be active/enabled) and then updates |
| the stencil values of a subset of the accessible samples (see above) |
| in the framebuffer. |
| |
| If /path/ does not name an existing path object, the command does |
| nothing (and no error is generated). |
| |
| The path object's stroke width parameter (PATH_STROKE_WIDTH_NV) in |
| path space units determines the width of the path's stroked region. |
| |
| When the dash array count of a path object is zero (dashing is |
| considered subsequently), the stroke of a transformed path's outline |
| is the region of window space defined by the union of: |
| |
| * Sweeping an orthogonal centered line segment of the (above |
| determined) effective stroke width along each path segment |
| in the path's transformed outline. |
| |
| * End cap regions (explained below) appended to the initial |
| and terminal control points of non-closed command sequences |
| in the path. For a sequence of commands that form a closed |
| contour, the end cap regions are ignored. |
| |
| * Join style regions (explained below) between connected path |
| segments meet. |
| |
| Any accessible samples within the union of these three regions are |
| considered within the path object's stroke. |
| |
| The /mask/ parameter controls what subset of stencil bits are affected |
| by the command. If the /mask/ parameter is zero, the path object's |
| stroke mask parameter (PATH_STROKE_MASK_NV) is considered the effective |
| value of /mask/. |
| |
| A sample's stencil bits that are set in the effective /mask/ value |
| are updated with the specified stencil /reference/ value if the |
| sample is accessible (as specified above) and within the stroke of |
| the transformed path's outline. |
| |
| Every path object has an initial and terminal end cap parameter |
| (PATH_INITIAL_END_CAP_NV and PATH_TERMINAL_END_CAP_NV) that is |
| one of FLAT, SQUARE_NV, ROUND_NV, or TRIANGULAR_NV. There are no |
| samples within a FLAT end cap. The SQUARE_NV cap extends centered |
| and tangent to the given end (initial or terminal) of the subpath |
| for half the effective stroke width; in other words, a square cap |
| is a half-square that kisses watertightly the end of a subpath. |
| The ROUND_NV cap appends a semi-circle, centered and tangent, |
| with the diameter of the effective stroke width to the given end |
| (initial or terminal) of the subpath; in other words, a round cap |
| is a semi-circle that kisses watertightly the end of a subpath. |
| The TRIANGULAR_NV cap appends a right triangle, centered and tangent, |
| with its hypotenuse flush to the given end of the subpath; in other |
| words, a triangular cap is a right triangle that kisses watertightly |
| the end of a subpath with the triangle's longest side. |
| |
| Every path object has a join style parameter (PATH_JOIN_STYLE_NV) |
| that is one of BEVEL_NV, ROUND_NV, MITER_REVERT_NV, MITER_TRUNCATE_NV, |
| or NONE; each path object also has a miter limit value. The BEVEL_NV |
| join style inserts a triangle with two vertices at the outside |
| corners where two connected path segments join and a third vertex at |
| the common end point shared by the two path segments. The ROUND_NV |
| join style inserts a wedge-shaped portion of a circle centered at |
| the common end point shared by the two path segments; the radius of |
| the circle is half the effective stroke width. There are no samples |
| within a NONE join style. The MITER_REVERT_NV join style inserts a |
| quadrilateral with two opposite vertices at the outside corners where |
| the two connected path segments join and two opposite vertices with |
| one on the path's junction between the two joining path segments and |
| the other at the common end point shared by the two path segments. |
| However, the MITER_REVERT_NV join style behaves as the BEVEL_NV |
| style if the sine of half the angle between the two joined segments |
| is less than the path object's PATH_STROKE_WIDTH value divided by |
| the path's PATH_MITER_LIMIT_NV value. The MITER_TRUNCATE_NV join |
| style is similar to MITER_REVERT_NV but rather than reverting to a |
| bevel when the miter limit is exceeded, instead the tip of the miter |
| quadrilateral is truncated such that the miter does not extend beyond |
| the miter limit. |
| |
| When the dash array count of a path object is /not/ zero, the path is |
| broken up into a sequence of paths based on the path object's dash |
| array count, dash array, dash offset, and dash cap parameters (see |
| section 5.X.1.5). This sequence of paths are handled as if their |
| dash count array is zero so their stroked region can be determined |
| for this stroking case that has already been explained. |
| |
| The dash pattern defined by the dash array is a sequence of lengths of |
| alternating "on" and "off" dash segments. The first (0th) element of |
| the dash array defines the length, in path space, of the first "on" |
| dash segment. The second value defines the length of the following |
| "off" segment. Each subsequent pair of values defines on "on" |
| and one "off" segment. |
| |
| The initial cap of the first dash segment uses the path's initial |
| dash cap style state (PATH_INITIAL_END_CAP_NV) as the effective |
| initial end cap for this first dash segment; the terminal cap |
| of the last dash segment uses the path's terminal dash cap style |
| state (PATH_TERMINAL_END_CAP_NV) as the effective terminal cap for |
| this last dash segment; all other caps of dash segments use the |
| PATH_INITIAL_DASH_CAP_NV for the initial cap of the segment and the |
| PATH_TERMINAL_DASH_CAP_NV for the terminal cap of the segment. |
| |
| The MOVE_TO_RESETS_NV value for a path's dash offset reset parameter |
| (PATH_DASH_OFFSET_RESET_NV) means that the dash offset resets to the |
| path's dash offset parameter upon a MOVE_TO_NV, RELATIVE_MOVE_TO_NV, |
| RESTART_PATH_NV, or RECT_NV command (an command that does an implicit |
| or explicit move-to) while dashing the path's command sequence. |
| The MOVE_TO_CONTINUES_NV value means that the dash pattern |
| progresses normally (without reset) when dashing a MOVE_TO_NV or |
| RELATIVE_MOVE_TO_NV command. |
| |
| Every path object has a stroke approximation bound parameter |
| (PATH_STROKE_BOUND_NV) that is a floating-point value /sab/ clamped |
| between 0.0 and 1.0 and set and queried with the PATH_STROKE_BOUND_NV |
| path parameter. Exact determination of samples swept an orthogonal |
| centered line segment along cubic Bezier segments and rational |
| quadratic Bezier curves (so non-circular partial elliptical arcs) is |
| intractable for real-time rendering so an approximation is required; |
| /sab/ intuitively bounds the approximation error as a percentage of |
| the path object's stroke width. Specifically, this path parameter |
| requests the implementation to stencil any samples within /sweep/ |
| object space units of the exact sweep of the path's cubic Bezier |
| segments or partial elliptical arcs to be sampled by the stroke where |
| |
| sweep = ((1-sab)*sw)/2 |
| |
| where /sw/ is the path object's stroke width. The initial value |
| of /sab/ when a path is created is 0.2. In practical terms, this |
| initial value means the stencil sample positions coverage within 80% |
| (100%-20%) of the stroke width of cubic and rational quadratic stroke |
| segments should be sampled. |
| |
| If the path object's client length parameter (PATH_CLIENT_LENGTH_NV) |
| value /clen/ is non-zero, prior to generating the dashed segments, the |
| dash pattern and dash offset lengths should be scaled by (multiplied |
| by) the clen/plen where /plen/ is the path object's computed length |
| (PATH_COMPUTED_LENGTH_NV). |
| |
| 5.X.2.2 Path Covering |
| |
| COVERING FILLED PATHS |
| |
| The command |
| |
| void PathCoverDepthFuncNV(enum zfunc); |
| |
| configures the depth function to be used by the CoverFillPathNV and |
| CoverStrokePathNV commands described subsequently. The /zfunc/ parameter |
| accepts the same values allowed by the DepthFunc command. |
| |
| The command |
| |
| void CoverFillPathNV(uint path, enum coverMode); |
| |
| transforms into window space the outline of the path object named |
| /path/ based on the current modelview, projection, viewport, |
| and depth range transforms (ignoring any vertex and/or geometry |
| shader or program that might be active/enabled) and rasterizes a |
| subset of the accessible samples in the framebuffer guaranteed to |
| include all samples that would be have a net stencil value change if |
| StencilFillPathNV were issued with the same modelview, projection, |
| and viewport state. During this rasterization, the stencil test |
| operates normally and as configured; the expectation is the stencil |
| test will be used to discard samples not determined "covered" by a |
| prior StencilFillPathNV command. The depth function, if DEPTH_TEST is |
| enabled, during this rasterization uses the function specified by |
| PathCoverDepthFuncNV (instead of the state specified by DepthFunc). |
| |
| If /path/ does not name an existing path object, the command does |
| nothing (and no error is generated). |
| |
| /coverMode/ must be one of CONVEX_HULL_NV, BOUNDING_BOX_NV, or |
| PATH_FILL_COVER_MODE_NV. The PATH_FILL_COVER_MODE_NV uses the path |
| object's PATH_FILL_COVER_MODE_NV parameter value as the effective |
| fill cover mode of the cover command. |
| |
| When /coverMode/ is CONVEX_HULL_NV or BOUNDING_BOX_NV, the subset |
| of accessible pixels that are rasterized are within a convex |
| hull or bounding box respectively (each expected to be reasonably |
| tight) surrounding all the samples guaranteed to be rasterized by |
| CoverFillPathNV. The bounding box must be orthogonally aligned |
| to the path space coordinate system. (The area of the bounding |
| box in path space is guaranteed to be greater than or equal the |
| area of the convex hull in path space.) Each rasterized sample |
| will be rasterized once and exactly once when CONVEX_HULL_NV or |
|