%% options copyright owner = Dirk Krause copyright year = 2011-xxxx license = bsd %% header #include #include /** Maximum input line size for Fig file. Although the Fig Format 3.2 specification does not set any limit for line sizes in Fig files we want to provide a buffer for input lines, so we must specify a buffer size. */ #define DK3_FIG_LINE_SIZE 1024 /** Maximum difference to treat coordinates as equal. */ #define DK3_FIG_EPSILON 1.0e-6 /** @defgroup dk3figoperations Draw operations. */ /**@{*/ /** Path operation: stroke. */ #define DK3_FIG_OP_STROKE 1 /** Path operation: fill. */ #define DK3_FIG_OP_FILL 2 /** Path operation: draw fill pattern. */ #define DK3_FIG_OP_PATTERN 4 /**@}*/ /** @defgroup dk3figcolors Fig colors */ /**@{*/ /** Use default color. */ #define DK3_FIG_COLOR_DEFAULT (-1) /** Black. */ #define DK3_FIG_COLOR_BLACK 0 /** Blue. */ #define DK3_FIG_COLOR_BLUE 1 /** Green. */ #define DK3_FIG_COLOR_GREEN 2 /** Cyan. */ #define DK3_FIG_COLOR_CYAN 3 /** Red. */ #define DK3_FIG_COLOR_RED 4 /** Magenta. */ #define DK3_FIG_COLOR_MAGENTA 5 /** Yellow. */ #define DK3_FIG_COLOR_YELLOW 6 /** White. */ #define DK3_FIG_COLOR_WHITE 7 /** Blue, 20 percent. */ #define DK3_FIG_COLOR_20_BLUE 8 /** Blue, 40 percent. */ #define DK3_FIG_COLOR_40_BLUE 9 /** Blue, 60 percent. */ #define DK3_FIG_COLOR_60_BLUE 10 /** Blue, 80 percent. */ #define DK3_FIG_COLOR_80_BLUE 11 /** Green, 25 percent. */ #define DK3_FIG_COLOR_25_GREEN 12 /** Green, 50 percent. */ #define DK3_FIG_COLOR_50_GREEN 13 /** Green, 75 percent. */ #define DK3_FIG_COLOR_75_GREEN 14 /** Cyan, 25 percent. */ #define DK3_FIG_COLOR_25_CYAN 15 /** Cyan, 50 percent. */ #define DK3_FIG_COLOR_50_CYAN 16 /** Cyan, 75 percent. */ #define DK3_FIG_COLOR_75_CYAN 17 /** Red, 25 percent. */ #define DK3_FIG_COLOR_25_RED 18 /** Red, 50 percent. */ #define DK3_FIG_COLOR_50_RED 19 /** Red, 75 percent. */ #define DK3_FIG_COLOR_75_RED 20 /** Magenta, 25 percent. */ #define DK3_FIG_COLOR_25_MAGENTA 21 /** Magenta, 50 percent. */ #define DK3_FIG_COLOR_50_MAGENTA 22 /** Magenta, 75 percent. */ #define DK3_FIG_COLOR_75_MAGENTA 23 /** Brown, 33 percent. */ #define DK3_FIG_COLOR_33_BROWN 24 /** Brown, 66 percent. */ #define DK3_FIG_COLOR_66_BROWN 25 /** Brown. */ #define DK3_FIG_COLOR_BROWN 26 /** Pink, 25 percent. */ #define DK3_FIG_COLOR_25_PINK 27 /** Pink, 50 percent. */ #define DK3_FIG_COLOR_50_PINK 28 /** Pink, 75 percent. */ #define DK3_FIG_COLOR_75_PINK 29 /** Pink. */ #define DK3_FIG_COLOR_PINK 30 /** Gold. */ #define DK3_FIG_COLOR_GOLD 31 /**@}*/ /** @defgroup dk3figobjtypes Fig object types */ /**@{*/ /** Color definition. */ #define DK3_FIG_OBJ_COLOR 0 /** Ellipse. */ #define DK3_FIG_OBJ_ELLIPSE 1 /** Polyline, polygon. */ #define DK3_FIG_OBJ_POLYLINE 2 /** Spline. */ #define DK3_FIG_OBJ_SPLINE 3 /** Text. */ #define DK3_FIG_OBJ_TEXT 4 /** Arc. */ #define DK3_FIG_OBJ_ARC 5 /** Compound object. Compound objects are resolved while reading the Fig file. */ #define DK3_FIG_OBJ_COMPOUND 6 /** End of compound object. */ #define DK3_FIG_OBJ_ENDCOMPOUND (-6) /** Not in Fig format definition, used for arrowheads 6/0 and 6/1. Subtype 0: stroked only, 1: closed, filled. The cl attribute must be set correctly. This object type can not appear as primary object, only in arrowheads. */ #define DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE 100 /** Not in Fig format definition, used for arrowheads. Subtype 0: Open spline. Subtype 1: Closed spline. The cl attribute must be set correctly. This object type can not appear as primary object, only in arrowheads. */ #define DK3_FIG_OBJ_PSEUDO_FAST_SPLINE 101 /**@}*/ /** @defgroup dk3figsubtypes Fig object subtypes */ /**@{*/ /** Arc sub type: Open. */ #define DK3_FIG_OBJ_SUB_ARC_OPEN 1 /** Arc sub type: Closed. */ #define DK3_FIG_OBJ_SUB_ARC_CLOSED 2 /** Ellipse sub type: Defined by radii. */ #define DK3_FIG_OBJ_SUB_ELL_RADII 1 /** Ellipse sub type: Defined by diameters. */ #define DK3_FIG_OBJ_SUB_ELL_DIAMETERS 2 /** Ellipse sub type: Circle defined by radius. */ #define DK3_FIG_OBJ_SUB_CIR_RADIUS 3 /** Ellipse sub type: Circle defined by diameter. */ #define DK3_FIG_OBJ_SUB_CIR_DIAMETER 4 /** Polyline sub type: Polyline. */ #define DK3_FIG_OBJ_SUB_POLYLINE 1 /** Polyline sub type: Box. */ #define DK3_FIG_OBJ_SUB_BOX 2 /** Polyline sub type: Polygon. */ #define DK3_FIG_OBJ_SUB_POLYGON 3 /** Polyline sub type: Arc-box. */ #define DK3_FIG_OBJ_SUB_ARCBOX 4 /** Polyline sub type: Embedded image. */ #define DK3_FIG_OBJ_SUB_IMAGE 5 /** Spline sub type: Open approximated spline. */ #define DK3_FIG_OBJ_SUB_OPEN_APPRO 0 /** Spline sub type: Closed approximated spline. */ #define DK3_FIG_OBJ_SUB_CLOSED_APPRO 1 /** Spline sub type: Open interpolated spline. */ #define DK3_FIG_OBJ_SUB_OPEN_INT 2 /** Spline sub type: Closed interpolated spline. */ #define DK3_FIG_OBJ_SUB_CLOSED_INT 3 /** Spline sub type: Open X-spline. */ #define DK3_FIG_OBJ_SUB_OPEN_X 4 /** Spline sub type: Closed X-spline. */ #define DK3_FIG_OBJ_SUB_CLOSED_X 5 /**@}*/ /** @defgroup dk3figlinestyles Fig line styles */ /**@{*/ /** Default line style. */ #define DK3_FIG_LS_DEFAULT (-1) /** Solid line. */ #define DK3_FIG_LS_SOLID 0 /** Dashed line. */ #define DK3_FIG_LS_DASHED 1 /** Dotted line. */ #define DK3_FIG_LS_DOTTED 2 /** Dash dot line. */ #define DK3_FIG_LS_DASH_DOTTED 3 /** Dash dot dot line. */ #define DK3_FIG_LS_DASH_DOUBLE_DOTTED 4 /** Dash dot dot dot line. */ #define DK3_FIG_LS_DASH_TRIPLE_DOTTED 5 /**@}*/ /** @defgroup dk3figlinejoin Line join style */ /**@{*/ /** Mitered line join. */ #define DK3_FIG_LJ_MITER 0 /** Rounded line join. */ #define DK3_FIG_LJ_ROUND 1 /** Beveled line join. */ #define DK3_FIG_LJ_BEVEL 2 /**@}*/ /** @defgroup dk3figlinecap Fig line cap style */ /**@{*/ /** Butted line cap. */ #define DK3_FIG_LC_BUTT 0 /** Rounded line cap. */ #define DK3_FIG_LC_ROUND 1 /** Projecting line cap. */ #define DK3_FIG_LC_PROJECTING 2 /**@}*/ /** @defgroup dk3figarrowstyles Fig arrow styles */ /**@{*/ /** Polyline arrow head. */ #define DK3_FIG_AS_STICK 0 /** Polygon arrow head. */ #define DK3_FIG_AS_CLOSED 1 /** Arrow with indented butt. */ #define DK3_FIG_AS_INDENTED 2 /** Arrow with pointed butt. */ #define DK3_FIG_AS_POINTED 3 /** Arrow with rhombus. */ #define DK3_FIG_AS_RHOMBUS 4 /** Line end with circle. */ #define DK3_FIG_AS_FULL_CIRCLE_END 5 /** Line end with half circle. */ #define DK3_FIG_AS_HALF_CIRCLE_END 6 /** Line end with rectangle. */ #define DK3_FIG_AS_RECTANGLE 7 /** Arrow inverted arrowhead. */ #define DK3_FIG_AS_INVERSE 8 /** Arrow only one side filled. */ #define DK3_FIG_AS_INDENTED_FILLED_HALF 9 /** Arrow only one side drawn (and filled). */ #define DK3_FIG_AS_CLOSED_HALF 10 /** Arrow indented, only one side drawn (and filled). */ #define DK3_FIG_AS_INDENTED_HALF 11 /** Arrow butted, only one side drawn (and filled). */ #define DK3_FIG_AS_BUTTED_HALF 12 /** Line end with triangle fork or overstroke. */ #define DK3_FIG_AS_TRIANGLE_FORK 13 /** Line end with forward or backward rectangle fork. */ #define DK3_FIG_AS_RECTANGLE_FORK 14 /**@}*/ /** @defgroup dk3figarrowfill Fig arrow head fill style */ /**@{*/ /** Hollow arrow head (white filled). */ #define DK3_FIG_AF_HOLLOW 0 /** Filled arrow head. */ #define DK3_FIG_AF_FILLED 1 /**@}*/ /** @defgroup dk3figfonts Fig fonts */ /**@{*/ /** LaTeX font: Default font. */ #define DK3_FIG_FONT_LATEX_DEFAULT 0 /** LaTeX font: Roman font. */ #define DK3_FIG_FONT_LATEX_ROMAN 1 /** LaTeX font: Bold font (roman). */ #define DK3_FIG_FONT_LATEX_BOLD 2 /** LaTeX font: Italic font (roman). */ #define DK3_FIG_FONT_LATEX_ITALIC 3 /** LaTeX font: Sans-serif. */ #define DK3_FIG_FONT_LATEX_SANS_SERIF 4 /** LaTeX font: Typewriter. */ #define DK3_FIG_FONT_LATEX_TYPEWRITER 5 /**@}*/ /** @defgroup dk3figfontflags Fig font flags */ /**@{*/ /** Rigid text (not scaled when scaling a compound). */ #define DK3_FIG_FONT_FLAG_RIGID 1 /** LaTeX special text. */ #define DK3_FIG_FONT_FLAG_SPECIAL 2 /** PS font in use (LaTeX font otherwise). */ #define DK3_FIG_FONT_FLAG_PS 4 /** Hidden text. */ #define DK3_FIG_FONT_FLAG_HIDDEN 8 /**@}*/ /** @defgroup figsrctypes Fig source types */ /**@{*/ /** Creator software unknown. */ #define DK3_FIG_SRCTYPE_UNKNOWN (-1) /** Fig created by XFig. */ #define DK3_FIG_SRCTYPE_XFIG 0 /** File created by jFig. */ #define DK3_FIG_SRCTYPE_JFIG 1 /** File created by WinFIG. */ #define DK3_FIG_SRCTYPE_WINFIG 2 /**@}*/ /** @defgroup figreaderstates Fig reader states */ /**@{*/ /** Error occured. */ #define DK3_FIG_RD_STATE_ERROR (-1) /** Expecting file type line. */ #define DK3_FIG_RD_STATE_START 0 /** Waiting for line containing orientation. */ #define DK3_FIG_RD_STATE_EXPECT_ORIENTATION 1 /** Waiting for line containing justification. */ #define DK3_FIG_RD_STATE_EXPECT_JUSTIFICATION 2 /** Waiting for line containing units. */ #define DK3_FIG_RD_STATE_EXPECT_UNITS 3 /** Waiting for line containing paper size. */ #define DK3_FIG_RD_STATE_EXPECT_PAPERSIZE 4 /** Waiting for line containing magnification. */ #define DK3_FIG_RD_STATE_EXPECT_MAGNIFICATION 5 /** Waiting for line containing multiplage or singlepage. */ #define DK3_FIG_RD_STATE_EXPECT_MULTIPAGE 6 /** Waiting for line containing transparent color number. */ #define DK3_FIG_RD_STATE_EXPECT_TRANSPARENT 7 /** Waiting for line containing resolution and coordinate system. */ #define DK3_FIG_RD_STATE_EXPECT_RESOLUTION 8 /** Ready to start a new object. */ #define DK3_FIG_RD_STATE_READY 9 /** Expecting arc arrowhead forward. */ #define DK3_FIG_RD_STATE_ARC_ARROW_FORWARD 10 /** Expecting arc arrowhead backward. */ #define DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD 11 /** Expecting polyline arrowhead forward. */ #define DK3_FIG_RD_STATE_PL_ARROW_FORWARD 12 /** Expecting polyline arrowhead backward. */ #define DK3_FIG_RD_STATE_PL_ARROW_BACKWARD 13 /** Expecting polyline image file name. */ #define DK3_FIG_RD_STATE_PL_IMAGE 14 /** Expecting polyline point coordinates. */ #define DK3_FIG_RD_STATE_PL_POINTS 15 /** Expecting spline arrowhead forward. */ #define DK3_FIG_RD_STATE_SP_ARROW_FORWARD 16 /** Expecting spline arrowhead backward. */ #define DK3_FIG_RD_STATE_SP_ARROW_BACKWARD 17 /** Expecting spline point coordinates. */ #define DK3_FIG_RD_STATE_SP_POINTS 18 /** Expecting spline control values. */ #define DK3_FIG_RD_STATE_SP_CONTROL 19 /**@}*/ /** Fig polygon or polyline point. */ typedef struct { double x; /**< X coordinate. */ double y; /**< Y coordinate. */ } dk3_fig_poly_point_t; /** Fig X-spline point. */ typedef struct { double x; /**< X coordinate. */ double y; /**< Y coordinate. */ double s; /**< Shape factor. */ } dk3_fig_spline_point_t; /** One X-spline segment. */ typedef struct { dk3_fig_spline_point_t a; /**< Left neighbour control point. */ dk3_fig_spline_point_t b; /**< Left endpoing of segment. */ dk3_fig_spline_point_t c; /**< Right endpoint of segment. */ dk3_fig_spline_point_t d; /**< Right neighbour control point. */ double pa; /**< Function parameter for A fct. */ double pb; /**< Function parameter for B fct. */ double pc; /**< Function parameter for C fct. */ double pd; /**< Function parameter for D fct. */ double qa; /**< Function parameter for A fct. */ double qb; /**< Function parameter for B fct. */ double qc; /**< Function parameter for C fct. */ double qd; /**< Function parameter for D fct. */ double duadt; /**< Window fct A du/dt. */ double dubdt; /**< Window fct B du/dt. */ double ducdt; /**< Window fct C du/dt. */ double duddt; /**< Window fct D du/dt. */ double x; /**< X result. */ double y; /**< Y result. */ double dxdt; /**< dx/dt result. */ double dydt; /**< dy/dt result. */ int cb; /**< Compatibility bug flag. */ int ha; /**< Flag: Have point A. */ int hd; /**< Flag: Have point D. */ } dk3_xspline_segment_t; /** Fig arc details. */ typedef struct { double xc; /**< X center. */ double yc; /**< Y center. */ double ra; /**< Radius. */ double x1; /**< First x. */ double y1; /**< First y. */ double x2; /**< Second x. */ double y2; /**< Second y. */ double x3; /**< Third x. */ double y3; /**< Third y. */ double as; /**< Start alpha (if arrowhead back). */ double ae; /**< End alpha (if arrowhead forward). */ unsigned char di; /**< Direction: 0x00=clockwise, 0x01=counter. */ } dk3_fig_det_arc_t; /** Fig ellipse details. */ typedef struct { double an; /**< Angle (rotation) in radians. */ double cx; /**< Center x position. */ double cy; /**< Center y position. */ double rx; /**< Radius x. */ double ry; /**< Radius y. */ } dk3_fig_det_ell_t; /** Fig polygon/polyline details. */ typedef struct { char const *fn; /**< File name for embedded image. */ dk3_fig_poly_point_t *po; /**< Point data. */ double ra; /**< Radius for arc boxes. */ #if 1 double xs; /**< Start x (if arrowhead back). */ double ys; /**< Start y (if arrowhead back). */ double xe; /**< End x (if arrowhead forward). */ double ye; /**< End y (if arrowhead forward). */ #endif size_t np; /**< Number of points. */ int flf; /**< Flip flag. */ } dk3_fig_det_pol_t; /** Fig spline details. */ typedef struct { dk3_fig_spline_point_t *po; /**< Point data. */ double *fslc; /**< Full segment length cache. */ double ts; /**< Start t (if arrowhead back). */ double te; /**< End t (if arrowhead forward). */ size_t np; /**< Number of points. */ } dk3_fig_det_spl_t; /** Fig text details. */ typedef struct { char const *st; /**< String. */ double x; /**< X position. */ double y; /**< Y position. */ double an; /**< Rotation in radians. */ double fs; /**< Font size. */ double he; /**< Height. */ double wi; /**< Width. */ int fo; /**< Font, see @ref dk3figfonts. */ int ff; /**< Font flags, see @ref dk3figfontflags. */ } dk3_fig_det_txt_t; /** Half-circle, used for arrowheads. */ typedef struct { double cx; /**< Center point x. */ double cy; /**< Center point y. */ double ra; /**< Radius. */ double an; /**< Angle in radians, Fig space. */ } dk3_fig_det_hci_t; /** Fig object details. */ typedef union { dk3_fig_det_arc_t arc; /**< Arc details. */ dk3_fig_det_ell_t ell; /**< Ellipse details. */ dk3_fig_det_pol_t pol; /**< Polygon or polyline details. */ dk3_fig_det_spl_t spl; /**< Spline details. */ dk3_fig_det_txt_t txt; /**< Text details. */ dk3_fig_det_hci_t hci; /**< Half-circle for arrowhead. */ } dk3_fig_obj_det_t; /** Fig arrow head. */ typedef struct { void *o1; /**< Object 1 for arrowhead. */ void *o2; /**< Object 2 for arrowhead. */ double wi; /**< Width. */ double he; /**< Height. */ int as; /**< Style, see @ref dk3figarrowstyles. */ int af; /**< Fill style, see @ref dk3figarrowfill. */ } dk3_fig_ah_t; /** Fig object. */ typedef struct { dk3_fig_obj_det_t dt; /**< Object details, type-specific. */ dk3_fig_ah_t *af; /**< Arrow details forward. */ dk3_fig_ah_t *ab; /**< Arrow details backward. */ void *dsd; /**< Driver specific details. */ double sv; /**< Style value (1/80) inch. */ unsigned long li; /**< Line number of object definition. */ int la; /**< Layer number. */ int ot; /**< Object type, see @ref dk3figobjtypes. */ int st; /**< Object subtype, see @ref dk3figsubtypes. */ int lw; /**< Line width (1/80 inch). */ int pc; /**< Pen+text color, see @ref dk3figcolors. */ int fc; /**< Fill color, see @ref dk3figcolors. */ int fi; /**< Area fill type. */ int cs; /**< Cap style, see @ref dk3figlinecap. */ int js; /**< Join style, see @ref dk3figlinejoin. */ int ls; /**< Line style, see @ref dk3figlinestyles. */ unsigned char cl; /**< Flag: Closed object. */ } dk3_fig_obj_t; /** Fig color. */ typedef struct { int i; /**< Color number. */ int r; /**< Red component. */ int g; /**< Green component. */ int b; /**< Blue component. */ } dk3_fig_color_t; /** Fig drawing. */ typedef struct { dk3_bb_t bb; /**< Bounding box in Fig units. */ dkChar const * const *msg; /**< Localized Fig messages. */ dk3_app_t *app; /**< Application structure. */ dk3_sto_t *sobj; /**< Storage for objects. */ dk3_sto_it_t *iobj; /**< Iterator for objects storage. */ dk3_sto_t *scol; /**< Storage for colors. */ dk3_sto_it_t *icol; /**< Iterator for colors storage. */ dk3_fig_obj_t *cobj; /**< Current object. */ void *dsd; /**< Driver specific details. */ double res; /**< Resolution. */ double arcspp; /**< Spline points per arc. */ double splspp; /**< Spline points per interval. */ double xsprec; /**< Precision for iterations. */ double lwbp; /**< Base line width in bp. */ unsigned long lineno; /**< Line number. */ long lres; /**< Resolution as integer value. */ size_t cind; /**< Current point index. */ size_t xssbs; /**< X-spline segements Bezier segs. */ size_t qbs; /**< Quadrant Bezier segments. */ size_t minspp; /**< Minimum spline points for arc. */ size_t codi; /**< Color digits. */ int cxy; /**< Flag: Read x (0) or y (1). */ int ec; /**< Error code. */ int state; /**< Reader state. */ int transcol; /**< Transparent color. */ int srctype; /**< Source type. */ int coah; /**< Flag: Compatible arrowheads. */ int xsah; /**< Flag: X-spline arrowheads. */ int cosp; /**< Flag: Compatible splines. */ int cofop; /**< Flag: Compat filled open paths. */ int bbts; /**< Flag: Use text size for bb. */ } dk3_fig_drawing_t; /** Fig document consisting of multiple pages. */ typedef struct { dk3_sto_t *sdrw; /**< Storage for Fig drawings. */ dk3_sto_it_t *idrw; /**< Iterator through drawing storage. */ } dk3_fig_writer_t; /** Graphics state. */ typedef struct { dk3_rgb_color_t c1; /**< Current color or stroke color. */ dk3_rgb_color_t c2; /**< Non-stroking color if applicable. */ double lw; /**< Line width. */ double sv; /**< Style value. */ double slw; /**< Dash line width. */ double fs; /**< Font size. */ int lc; /**< Line cap, see @ref dk3figlinecap. */ int lj; /**< Line join, see @ref dk3figlinejoin. */ int ls; /**< Line style, see @ref dk3figlinestyles. */ int fn; /**< PS font number. */ int hc1; /**< Flag: c1 is set. */ int hc2; /**< Flag: c2 is set. */ int hlc; /**< Flag: lc is set. */ int hlj; /**< Flag: lj is set. */ int hlw; /**< Flag: lw is set. */ int hls; /**< Flag: ls is set. */ int hfn; /**< Flag: fn and fs set. */ } dk3_graphics_state_t; /** Font as specified in the Fig file. */ typedef struct { int psfont; /**< Flag: PS font (1) or LaTeX font (0). */ int fontno; /**< Font number. */ double fontsz; /**< Font size. */ } dk3_fig_font_t; #ifdef __cplusplus extern "C" { #endif /* dk3fig module ============= */ /** Get localized message texts. @param app Application structure. @return Pointer to localized message texts on success, NULL on error. */ dkChar const * const * dk3fig_get_localized_messages(dk3_app_t *app); /** Create a new drawing structure. @param app Application structure, must not be NULL. @param msg Localized messages texts from dk3fig module. @return Pointer to new structure on success, NULL on error. */ dk3_fig_drawing_t * dk3fig_drawing_new(dk3_app_t *app, dkChar const * const *msg); /** Set detail options for drawing. @param drw Drawing to set up. @param xssbs Number of Bezier segments for each X-spline segment. @param qbs Number of Bezier segments for a 90 degree arc. */ void dk3fig_set_options_bsegs(dk3_fig_drawing_t *drw, size_t xssbs, size_t qbs); /** Set base line width in bp. @param drw Drawing to set up. @param val New value. */ void dk3fig_set_options_lwbp(dk3_fig_drawing_t *drw, double val); /** Set flag for compatible arrowheads. @param drw Drawing to set up. @param val Flag value. */ void dk3fig_set_options_coah(dk3_fig_drawing_t *drw, int val); /** Set flag for X-spline arrowheads (only used, when compatible arrowheads not used). @param drw Drawing to set up. @param val Flag value. */ void dk3fig_set_options_xsah(dk3_fig_drawing_t *drw, int val); /** Set flag for compatible splines (reproduce XFig/fig2dev interpolated spline bug). @param drw Drawing to set up. @param val Flag value. */ void dk3fig_set_options_cosp(dk3_fig_drawing_t *drw, int val); /** Set flag for bounding box with text sizes. @param drw Drawing to set up. @param val Flag value. */ void dk3fig_set_options_bbts(dk3_fig_drawing_t *drw, int val); /** Set flag for compatible filled open paths. @param drw Drawing to set up. @param val Flag value. */ void dk3fig_set_options_cofop(dk3_fig_drawing_t *drw, int val); /** Set source type. @param drw Drawing to set up. @param val New source type value. */ void dk3fig_set_options_srctype(dk3_fig_drawing_t *drw, int val); /** Destroy drawing structure, release memory. @param drw Structure to destroy. */ void dk3fig_drawing_delete(dk3_fig_drawing_t *drw); /** Destroy Fig object, release memory. @param obj Object to destroy. */ void dk3fig_obj_delete(dk3_fig_obj_t *obj); /** Create new Fig object. @param li Line number of object definition. @param la Layer number. @param ot Object type. @param st Object subtype. @param lw Line width. @param pc Pen color. @param fc Fill color. @param fi Fill type. @param cs Cap style. @param js Join style. @param ls Line style. @param sv Style value. @param af Flag: Arrowhead forward. @param ab Flag: Arrowhead backward. @param np Number of spline/polyline points. @param txt Text string (for text objects). @param app Application structure for diagnostics, may be NULL. @return Pointer to new object on success, NULL on error. */ dk3_fig_obj_t * dk3fig_obj_new( unsigned long li, int la, int ot, int st, int lw, int pc, int fc, int fi, int cs, int js, int ls, double sv, int af, int ab, size_t np, char const *txt, dk3_app_t *app ); /** Initialize Fig object. @param obj Object to initialize. */ void dk3fig_obj_init(dk3_fig_obj_t *obj); /** Initialize graphics state data. @param gs Graphics state structure to initialize. */ void dk3fig_gs_init(dk3_graphics_state_t *gs); /** Set arrowhead spline options. @param drw Drawing to set up. @param arcspp Number of X-spline segments per 90 degree arc. @param splspp Number of X-spline segments per X-spline interval. @param minspp Minimum number of X-spline intervals for arrowhead edge. */ void dk3fig_set_options_arrows( dk3_fig_drawing_t *drw, double arcspp, double splspp, size_t minspp ); /** Set precision for X-splines iterations. @param drw Drawing to set up. @param prec Precision. */ void dk3fig_set_options_iteration_precision( dk3_fig_drawing_t *drw, double prec ); /** Set number of digits for colors. @param drw Drawing to set up. @param codi Number of color digits. */ void dk3fig_set_options_codi( dk3_fig_drawing_t *drw, size_t codi ); /** Set error code for drawing. The new error code is set only if the current error code of the drawing is 0 (indicates "no error found"). @param drw Drawing to set. @param ec Error code to set. */ void dk3fig_set_ec(dk3_fig_drawing_t *drw, int ec); #ifdef __cplusplus } #endif %% module #include "dk3all.h" #include "dk3fig.h" $!trace-include /** Localized message texts. */ static dkChar const * const dk3fig_messages[] = { $!string-table macro=dkT # # 0: File name. # dk3fig.str # # 1: Syntax error in Fig input! # Syntax error in Fig input! # # 2: Color redefinition! # Color redefined! # # 3: Math problem in arc calculation! # Mathematical problem in arc calculation! # # 4: Object processing failed! # Object processing failed! # # 5: Arrowhead calculation failed! # Arrowhead calculation failed! # # 6: Error while reading input file! # Error while reading input file! # # 7: Color not found, using black as default color! # Color not found, using black as default color! # # 8: Unknown object type! # Unknown object type! # # 9: Can not fill open graphics path! # Can not fill open graphics path! # # 10: Converted to closed graphics path for filling. # Converted to closed graphics path for filling. $!end }; dkChar const * const * dk3fig_get_localized_messages(dk3_app_t *app) { dkChar const * const *back = NULL; if(app) { back = dk3app_messages( app, dk3fig_messages[0], (dkChar const **)dk3fig_messages ); } return back; } /** Compare two text objects. This function is used to sort text objects. @param pl Left text object. @param pr Right text object. @return Comparison result. */ static int dk3fig_obj_text_compare(dk3_fig_obj_t const *pl, dk3_fig_obj_t const *pr) { int back = 0; /* Non-special texts before special texts. */ if(((pl->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL) { if(!(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL)) { back = 1; } } else { if(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL) { back = -1; } } /* Font selection type. */ if(0 == back) { if(((pl->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS) { if(!(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS)) { back = 1; } } else { if(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS) { back = -1; } } } /* Font number. */ if(0 == back) { if((pl->dt).txt.fo > (pr->dt).txt.fo) { back = 1; } else { if((pl->dt).txt.fo < (pr->dt).txt.fo) { back = -1; } } } /* Font size. */ if(0 == back) { if((pl->dt).txt.fs > (pr->dt).txt.fs) { back = 1; } else { if((pl->dt).txt.fs < (pr->dt).txt.fs) { back = -1; } } } /* Text string. */ if(0 == back) { back = dk3str_c8_cmp((pl->dt).txt.st, (pr->dt).txt.st); if(back < -1) back = -1; if(back > 1) back = 1; } return back; } /** Compare two non-text objects. @param pl Left object. @param pr Right object. @return Comparison result. */ static int dk3fig_obj_path_compare(dk3_fig_obj_t const *pl, dk3_fig_obj_t const *pr) { int back = 0; /* Line width. */ if(0 == back) { if(pl->lw > pr->lw) { back = 1; } else { if(pl->lw < pr->lw) { back = -1; } } } /* Pen color. */ if(0 == back) { if(pl->pc > pr->pc) { back = 1; } else { if(pl->pc < pr->pc) { back = -1; } } } /* Line cap. */ if(0 == back) { if(pl->cs > pr->cs) { back = 1; } else { if(pl->cs < pr->cs) { back = -1; } } } /* Line join. */ if(0 == back) { if(pl->js > pr->js) { back = 1; } else { if(pl->js < pr->js) { back = -1; } } } /* Line style, style value for equal line style. */ if(0 == back) { if(pl->ls > pr->ls) { back = 1; } else { if(pl->ls < pr->ls) { back = -1; } } if(0 == back) { if(pl->sv > pr->sv) { back = 1; } else { if(pl->sv < pr->sv) { back = -1; } } } } /* Non-closed before closed. */ if(0 == back) { if(pl->cl) { if(pr->cl) { /* Fill color. */ if(pl->fc > pr->fc) { back = 1; } else { if(pl->fc < pr->fc) { back = -1; } } /* Fill style. */ if(0 == back) { if(pl->fi > pr->fi) { back = 1; } else { if(pl->fi < pr->fi) { back = -1; } } } } else { back = 1; } } else { if(pr->cl) { back = -1; } } } /* Object type. */ if(0 == back) { if(pl->ot > pr->ot) { back = 1; } else { if(pl->ot < pr->ot) { back = -1; } } } /* Sub type. */ if(0 == back) { if(pl->st > pr->st) { back = 1; } else { if(pl->st < pr->st) { back = -1; } } } return back; } /** Compare two Fig objects for sorted storing. We must draw the deepest layer elements first (by definition). Additionally we sort elements by multiple attributes (non-text elements before texts, pen color, fill color and type, line style, line width, cap style, join style) to group elements with equal attributes. This is done to minimize instructions for writing colors, line style, line width... @param l Left Fig object. @param r Right Fig object. @param cr Comparison criteria (ignored). @return Comparison result. */ static int dk3fig_obj_compare(void const *l, void const *r, int cr) { int back = 0; dk3_fig_obj_t const *pl; dk3_fig_obj_t const *pr; if(l) { if(r) { pl = (dk3_fig_obj_t const *)l; pr = (dk3_fig_obj_t const *)r; /* Deepest layers first. */ if(pl->la > pr->la) { back = -1; } else { if(pl->la < pr->la) { back = 1; } } /* Non-texts before texts. */ if(0 == back) { if(DK3_FIG_OBJ_TEXT == pl->ot) { if(!(DK3_FIG_OBJ_TEXT == pr->ot)) { back = 1; } else { back = dk3fig_obj_text_compare(pl, pr); } } else { if(DK3_FIG_OBJ_TEXT == pr->ot) { back = -1; } else { back = dk3fig_obj_path_compare(pl, pr); } } } /* Line number of definition. */ if(0 == back) { if(pl->li > pr->li) { back = 1; } else { if(pl->li < pr->li) { back = -1; } } } } else back = 1; } else { if(r) back = -1; } return back; } /** Destroy arrowhead, release memory. @param ah Arrowhead to destroy. */ static void dk3fig_ah_delete(dk3_fig_ah_t *ah) { $? "+ dk3fig_ah_delete %!8s", TR_8PTR(ah) if(ah) { if(ah->o1) { $? ". Fig object 1" dk3fig_obj_delete((dk3_fig_obj_t *)(ah->o1)); } if(ah->o2) { $? ". Fig object 2" dk3fig_obj_delete((dk3_fig_obj_t *)(ah->o2)); } dk3_delete(ah); } $? "- dk3fig_ah_delete" } /** Create new arrowhead structure. @param app Application structure for diagnostics. @return Pointer to new structure on success, NULL on error. */ static dk3_fig_ah_t * dk3fig_ah_new(dk3_app_t *app) { dk3_fig_ah_t *back = NULL; back = dk3_new_app(dk3_fig_ah_t,1,app); if(back) { back->o1 = NULL; back->o2 = NULL; back->wi = 0.0; back->he = 0.0; back->as = 0; back->af = 0; } return back; } void dk3fig_obj_delete(dk3_fig_obj_t *obj) { $? "+ dk3fig_obj_delete %!8s", TR_8PTR(obj) if(obj) { if(obj->af) { $? ". arrowhead forward" dk3fig_ah_delete(obj->af); } if(obj->ab) { $? ". arrowhead backward" dk3fig_ah_delete(obj->ab); } switch(obj->ot) { case DK3_FIG_OBJ_TEXT: { $? ". text" if((obj->dt).txt.st) { dk3_release((obj->dt).txt.st); } } break; case DK3_FIG_OBJ_SPLINE: { $? ". spline" if((obj->dt).spl.po) { dk3_release((obj->dt).spl.po); } if((obj->dt).spl.fslc) { dk3_release((obj->dt).spl.fslc); } } break; case DK3_FIG_OBJ_POLYLINE: { $? ". polyline" if((obj->dt).pol.po) { dk3_release((obj->dt).pol.po); } if((obj->dt).pol.fn) { dk3_release((obj->dt).pol.fn); } } break; } obj->af = NULL; obj->ab = NULL; dk3_delete(obj); } $? "- dk3fig_obj_delete" } /** Reset all members of a drawing object. @param drw Drawing object to reset. */ static void dk3fig_initialize_empty_drawing(dk3_fig_drawing_t *drw) { $? "+ dk3fig_initialize_empty_drawing %!8s", TR_8PTR(drw) dk3bb_reset(&(drw->bb)); drw->msg = NULL; drw->app = NULL; drw->sobj = NULL; drw->iobj = NULL; drw->scol = NULL; drw->icol = NULL; drw->cobj = NULL; drw->dsd = NULL; drw->res = 1200.0; drw->lineno = 0UL; drw->lres = 0; drw->cind = 0; drw->cxy = 0; drw->state = 0; drw->ec = 0; drw->srctype = DK3_FIG_SRCTYPE_UNKNOWN; drw->xssbs = 8; drw->qbs = 4; drw->transcol = -2; drw->coah = 0; drw->xsah = 0; drw->cosp = 0; drw->cofop = 1; drw->bbts = 0; drw->arcspp = 8.0; drw->splspp = 8.0; drw->minspp = 4; drw->codi = 3; drw->xsprec = 0.04; /* originally 1200.0 / 25400.0 */ drw->lwbp = 0.9; /* 1/80 inch */ $? "- dk3fig_initialize_empty_drawing" } /** Compare two Fig colors. @param l Left object. @param r Right color object or number. @param cr Comparison criteria (0=color/color, 1=color/number). @return Comparison result. */ static int dk3fig_color_compare(void const *l, void const *r, int cr) { int back = 0; dk3_fig_color_t const *pl; dk3_fig_color_t const *pr; int *ip; if(l) { if(r) { pl = (dk3_fig_color_t const *)l; pr = (dk3_fig_color_t const *)r; ip = (int *)r; switch(cr) { case 1: { if(pl->i > (*ip)) { back = 1; } else { if(pl->i < (*ip)) { back = -1; } } } break; default: { if(pl->i > pr->i) { back = 1; } else { if(pl->i < pr->i) { back = -1; } } } break; } } else back = 1; } else { if(r) back = -1; } return back; } dk3_fig_drawing_t * dk3fig_drawing_new(dk3_app_t *app, dkChar const * const *msg) { dk3_fig_drawing_t *back = NULL; $? "+ dk3fig_drawing_new %!8s", TR_8PTR(app) if(app) { back = dk3_new_app(dk3_fig_drawing_t,1,app); if(back) { dk3fig_initialize_empty_drawing(back); back->app = app; back->msg = msg; back->sobj = dk3sto_open_app(app); if(back->sobj) { dk3sto_set_comp(back->sobj, dk3fig_obj_compare, 0); back->iobj = dk3sto_it_open(back->sobj); if(back->iobj) { back->scol = dk3sto_open_app(app); if(back->scol) { dk3sto_set_comp(back->scol, dk3fig_color_compare, 0); back->icol = dk3sto_it_open(back->scol); if(back->icol) { /* Place for further initialization here */ } else { $? "! memory color iterator" dk3fig_drawing_delete(back); back = NULL; } } else { $? "! memory color storage" dk3fig_drawing_delete(back); back = NULL; } } else { $? "! memory iterator" dk3fig_drawing_delete(back); back = NULL; } } else { $? "! memory storage" dk3fig_drawing_delete(back); back = NULL; } } else { $? "! memory" } } $? "- dk3fig_drawing_new %!8s", TR_8PTR(back) return back; } void dk3fig_drawing_delete(dk3_fig_drawing_t *drw) { dk3_fig_color_t *co; /* Current color to release. */ dk3_fig_obj_t *po; /* Current Fig object to release. */ $? "+ dk3fig_drawing_delete %!8s", TR_8PTR(drw) if(drw) { /* Remove all objects. */ if(drw->sobj) { if(drw->iobj) { dk3sto_it_reset(drw->iobj); while(NULL != (po = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) { dk3fig_obj_delete(po); } dk3sto_it_close(drw->iobj); } dk3sto_close(drw->sobj); } /* Remove all colors. */ if(drw->scol) { if(drw->icol) { dk3sto_it_reset(drw->icol); while(NULL != (co = (dk3_fig_color_t *)dk3sto_it_next(drw->icol))) { $? ". delete color %d = %d %d %d", co->i, co->r, co->g, co->b dk3_delete(co); } dk3sto_it_close(drw->icol); } dk3sto_close(drw->scol); } /* Reset all members. */ dk3fig_initialize_empty_drawing(drw); /* Release memory. */ drw->app = NULL; drw->msg = NULL; dk3_delete(drw); } $? "- dk3fig_drawing_delete" } /** Internal function to create Fig object and initialize it. @param li Line number of object definition in file. @param la Layer number. @param ot Object type. @param st Object subtype. @param lw Line width. @param pc Pen color. @param fc Fill color. @param fi Fill type. @param cs Cap style. @param js Join style. @param ls Line style. @param sv Style value. @param af Flag: Arrowhead forward. @param ab Flag: Arrowhead backward. @param po Flag: Path object (non-text object). @param cl Flag: Closed path object. @param app Application structure for diagnostics, may be NULL. @return Pointer to new object on success, NULL on error. */ static dk3_fig_obj_t * dk3fig_obj_internal_new( unsigned long li, int la, int ot, int st, int lw, int pc, int fc, int fi, int cs, int js, int ls, double sv, int af, int ab, int po, int cl, dk3_app_t *app ) { dk3_fig_obj_t *back = NULL; $? "+ dk3fig_obj_internal_new po = %d cl = %d", po, cl back = dk3_new_app(dk3_fig_obj_t,1,app); if(back) { $? ". allocation ok" back->af = NULL; back->ab = NULL; back->dsd = NULL; back->sv = sv; back->li = li; back->la = la; back->ot = ot; back->st = st; back->lw = lw; back->pc = pc; back->fc = fc; back->fi = fi; back->cs = cs; back->js = js; back->ls = ls; back->cl = ((cl) ? 0x01 : 0x00); $? ". here" if(back->lw < 0) { back->lw = 0; if(po) { $? ". warning: illegal line width" /* +++++ Warning: Illegal line width corrected! */ } } if(back->pc < -1) { $? ". warning: illegal pen color" back->pc = -1; /* +++++ Warning: Illegal pen color definition corrected! */ } if(back->fc < DK3_FIG_COLOR_DEFAULT) { back->fc = DK3_FIG_COLOR_DEFAULT; if((po) && (cl)) { $? ". warning: illegal fill color" /* +++++ Warning: Illegal fill color definition corrected! */ } } if(back->fi < DK3_FIG_COLOR_DEFAULT) { back->fi = DK3_FIG_COLOR_DEFAULT; if((po) && (cl)) { $? ". warning: illegal fill style" /* +++++ Warning: Illegal fill style corrected! */ } } else { if(back->fi > 62) { back->fi = 62; if((po) && (cl)) { $? ". warning: illegal fill style" /* +++++ Warning: Illegal fill style corrected! */ } } else { if((DK3_FIG_COLOR_BLACK == fc) || (DK3_FIG_COLOR_WHITE == fc)) { if((back->fi >= 21) && (back->fi <= 40)) { back->fi = 20; if((po) && (cl)) { $? ". warning: illegal fill style" /* +++++ Warning: Illegal fill style corrected! */ } } } } } if(DK3_FIG_LC_BUTT != back->cs) { if(DK3_FIG_LC_ROUND != back->cs) { if(DK3_FIG_LC_PROJECTING != back->cs) { back->cs = DK3_FIG_LC_BUTT; if(po) { $? ". warning: illegal line cap" /* +++++ Warning: Illegal line cap style corrected! */ } } } } if(DK3_FIG_LJ_MITER != back->js) { if(DK3_FIG_LJ_ROUND != back->js) { if(DK3_FIG_LJ_BEVEL != back->js) { back->js = DK3_FIG_LJ_MITER; if(po) { $? ". warning: illegal join style" /* +++++ Warning: Illegal line join style corrected! */ } } } } if(back->ls < DK3_FIG_LS_SOLID) { back->ls = DK3_FIG_LS_SOLID; if(ls < DK3_FIG_LS_DEFAULT) { if(po) { $? ". warning: illegal line style" /* +++++ Warning: Illegal line style corrected! */ } } } else { if(back->ls > DK3_FIG_LS_DASH_TRIPLE_DOTTED) { back->ls = DK3_FIG_LS_SOLID; if(po) { $? ". warning: illegal line style" /* +++++ Warning: Illegal line style corrected! */ } } } } else { $? "! allocation failed" } if((po) && (!(cl))) { $? ". open path" if(NULL != back) { if(af) { $? ". have arrowhead forward" back->af = dk3fig_ah_new(app); if(!(back->af)) { dk3fig_obj_delete(back); back = NULL; } } } if (NULL != back) { if(ab) { $? ". have arrowhead backward" back->ab = dk3fig_ah_new(app); if(!(back->ab)) { dk3fig_obj_delete(back); back = NULL; } } } } else { $? ". closed path" if((af) || (ab)) { $? "! arrowhead ignored for closed path" /* +++++ Warning: Arrowhead ignored for closed path! */ } } $? "- dk3fig_obj_internal_new %!8s", TR_8PTR(back) return back; } /** Initialize details for arc. @param obj Object to initialize. */ static void dk3fig_initialize_arc_details(dk3_fig_obj_t *obj) { (obj->dt).arc.xc = 0.0; (obj->dt).arc.yc = 0.0; (obj->dt).arc.ra = 0.0; (obj->dt).arc.x1 = 0.0; (obj->dt).arc.y1 = 0.0; (obj->dt).arc.x2 = 0.0; (obj->dt).arc.y2 = 0.0; (obj->dt).arc.x3 = 0.0; (obj->dt).arc.y3 = 0.0; (obj->dt).arc.as = 0.0; (obj->dt).arc.ae = 0.0; (obj->dt).arc.di = 0x00; } /** Initialize ellipse details. @param obj Object to initialize. */ static void dk3fig_initialize_ellipse_details(dk3_fig_obj_t *obj) { (obj->dt).ell.an = 0.0; (obj->dt).ell.cx = 0.0; (obj->dt).ell.cy = 0.0; (obj->dt).ell.rx = 0.0; (obj->dt).ell.ry = 0.0; } /** Initialize polyline details. @param obj Object to initialize. @param np Number of points. @param app Application structure for diagnostics. @return 1 on success, 0 on error (not enough memory). */ static int dk3fig_initialize_polyline_details(dk3_fig_obj_t *obj,size_t np,dk3_app_t *app) { int back = 0; (obj->dt).pol.fn = NULL; (obj->dt).pol.po = NULL; (obj->dt).pol.ra = 0.0; (obj->dt).pol.xs = 0.0; (obj->dt).pol.ys = 0.0; (obj->dt).pol.xe = 0.0; (obj->dt).pol.ye = 0.0; (obj->dt).pol.np = np; (obj->dt).pol.flf = 0; (obj->dt).pol.po = dk3_new_app(dk3_fig_poly_point_t,np,app); if((obj->dt).pol.po) { back = 1; } return back; } /** Initialize spline details. @param obj Object to initialize. @param np Number of spline points. @param app Application structure for diagnostics. @return 1 on success, 0 on error (not enough memory). */ static int dk3fig_initialize_spline_details(dk3_fig_obj_t *obj,size_t np,dk3_app_t *app) { double *xptr; size_t i; int back = 0; (obj->dt).spl.po = NULL; (obj->dt).spl.fslc = NULL; (obj->dt).spl.ts = -1.0; (obj->dt).spl.te = -1.0; (obj->dt).spl.np = np; (obj->dt).spl.po = dk3_new_app(dk3_fig_spline_point_t, np, app); if((obj->dt).spl.po) { back = 1; switch(obj->st) { case 0: case 2: case 4: { if(((obj->af) || (obj->ab)) && (2 <= np)) { (obj->dt).spl.fslc = dk3_new_app(double, (np-1), app); if((obj->dt).spl.fslc) { /* Initialize cache to -1 */ xptr = (obj->dt).spl.fslc; i = np - 1; while(i--) { *(xptr++) = -1.0; } } else { back = 0; } } } break; } } return back; } /** Initialize text details. @param obj Object to initialize. @param tx Text for text object. @param app Application structure for diagnostics. @return 1 on success, 0 on error (not enough memory). */ static int dk3fig_initialize_text_details(dk3_fig_obj_t *obj,char const *tx,dk3_app_t *app) { int back = 0; (obj->dt).txt.st = NULL; (obj->dt).txt.x = 0.0; (obj->dt).txt.y = 0.0; (obj->dt).txt.an = 0.0; (obj->dt).txt.fs = 0.0; (obj->dt).txt.he = 0.0; (obj->dt).txt.wi = 0.0; (obj->dt).txt.fo = 0; (obj->dt).txt.ff = 0; (obj->dt).txt.st = dk3str_c8_dup_app(tx, app); if((obj->dt).txt.st) { back = 1; } return back; } dk3_fig_obj_t * dk3fig_obj_new( unsigned long li, int la, int ot, int st, int lw, int pc, int fc, int fi, int cs, int js, int ls, double sv, int af, int ab, size_t np, char const *txt, dk3_app_t *app ) { dk3_fig_obj_t *back = NULL; $? "+ dk3fig_obj_new ot = %d st = %d", ot, st if((la < 0) || (la > 999)) { /* +++++ Warning: Illegal layer number! */ } switch(ot) { case DK3_FIG_OBJ_ARC: { $? ". arc" switch(st) { case DK3_FIG_OBJ_SUB_ARC_OPEN: { $? ". open arc" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app ); } break; case DK3_FIG_OBJ_SUB_ARC_CLOSED: { $? ". closed arc" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; case 0: { $? ". closed arc (jFig)" /* +++++ Warning: jFig closed arc bug. */ back = dk3fig_obj_internal_new( li, la, ot, DK3_FIG_OBJ_SUB_ARC_CLOSED, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app ); } break; default: { $? "! unknown arc" /* +++++ Warning: Illegal sub type corrected! */ back = dk3fig_obj_internal_new( li, la, ot, DK3_FIG_OBJ_SUB_ARC_CLOSED, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app ); } break; } if(back) { dk3fig_initialize_arc_details(back); } } break; case DK3_FIG_OBJ_ELLIPSE: { $? ". ellipse" switch(st) { case DK3_FIG_OBJ_SUB_ELL_RADII: { $? ". ellipse by radii" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; case DK3_FIG_OBJ_SUB_ELL_DIAMETERS: { $? ". ellipse by diameters" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; case DK3_FIG_OBJ_SUB_CIR_RADIUS: { $? ". circle by radii" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; case DK3_FIG_OBJ_SUB_CIR_DIAMETER: { $? ". circle by diameters" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; default: { $? "! unknown ellipse type" /* +++++ Warning: Illegal sub type corrected! */ back = dk3fig_obj_internal_new( li, la, ot, DK3_FIG_OBJ_SUB_ELL_RADII, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; } if(back) { dk3fig_initialize_ellipse_details(back); } } break; case DK3_FIG_OBJ_POLYLINE: { $? ". polyline" switch(st) { case DK3_FIG_OBJ_SUB_POLYLINE: { $? ". polyline" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app ); } break; case DK3_FIG_OBJ_SUB_BOX: { $? ". box" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; case DK3_FIG_OBJ_SUB_POLYGON: { $? ". polygon" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; case DK3_FIG_OBJ_SUB_ARCBOX: { $? ". arc box" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; case DK3_FIG_OBJ_SUB_IMAGE: { $? ". image import" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; default: { $? "! unknown polyline type" /* +++++ Warning: Illegal sub type corrected! */ back = dk3fig_obj_internal_new( li, la, ot, DK3_FIG_OBJ_SUB_POLYLINE, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app ); } break; } if(back) { if(!dk3fig_initialize_polyline_details(back, np, app)) { dk3fig_obj_delete(back); back = NULL; } } } break; case DK3_FIG_OBJ_SPLINE: { $? ". spline" switch(st) { case DK3_FIG_OBJ_SUB_OPEN_APPRO: { $? ". open approximated" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app ); } break; case DK3_FIG_OBJ_SUB_CLOSED_APPRO: { $? ". closed approximated" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; case DK3_FIG_OBJ_SUB_OPEN_INT: { $? ". open interpolated" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app ); } break; case DK3_FIG_OBJ_SUB_CLOSED_INT: { $? ". closed interpolated" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; case DK3_FIG_OBJ_SUB_OPEN_X: { $? ". open x-spline" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app ); } break; case DK3_FIG_OBJ_SUB_CLOSED_X: { $? ". closed x-spline" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app ); } break; default: { $? "! unknown spline type" /* +++++ Warning: Illegal sub type corrected! */ back = dk3fig_obj_internal_new( li, la, ot, DK3_FIG_OBJ_SUB_OPEN_X, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app ); } break; } if(back) { if(!dk3fig_initialize_spline_details(back, np, app)) { dk3fig_obj_delete(back); back = NULL; } } } break; case DK3_FIG_OBJ_TEXT: { $? ". text" if(txt) { $? ". string available" back = dk3fig_obj_internal_new( li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 0, 0, app ); if(back) { if(!dk3fig_initialize_text_details(back, txt, app)) { dk3fig_obj_delete(back); back = NULL; } } } else { $? "! no text string available" /* +++++ ERROR: No text specified! */ } } break; case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: { $? ". half circle as arrowhead" back = dk3fig_obj_internal_new( li, la, ot, ((st) ? 1 : 0), lw, pc, fc, fi, cs, js, ls, sv, af, ab, 0, ((st) ? 1 : 0), app ); } break; default: { $? "! unknown" /* +++++ ERROR: Can not create object! */ } break; } $? "- dk3fig_obj_new %!8s", TR_8PTR(back) return back; } void dk3fig_obj_init(dk3_fig_obj_t *obj) { if(obj) { dk3mem_res((void *)obj, sizeof(dk3_fig_obj_t)); obj->af = NULL; obj->ab = NULL; obj->dsd = NULL; obj->sv = 0.0; } } void dk3fig_set_options_bsegs(dk3_fig_drawing_t *drw, size_t xssbs, size_t qbs) { if(drw) { drw->xssbs = xssbs; drw->qbs = qbs; if(xssbs < 2) drw->xssbs = 2; if(qbs < 2) drw->qbs = 2; } } void dk3fig_set_options_lwbp(dk3_fig_drawing_t *drw, double val) { if (drw) { drw->lwbp = val; } } void dk3fig_set_options_coah(dk3_fig_drawing_t *drw, int val) { if(drw) { drw->coah = ((val) ? 1 : 0); } } void dk3fig_set_options_xsah(dk3_fig_drawing_t *drw, int val) { if (drw) { drw->xsah = ((val) ? 1 : 0); } } void dk3fig_set_options_cosp(dk3_fig_drawing_t *drw, int val) { if(drw) { drw->cosp = ((val) ? 1 : 0); } } void dk3fig_set_options_bbts(dk3_fig_drawing_t *drw, int val) { if(drw) { drw->bbts = ((val) ? 1 : 0); } } void dk3fig_set_options_cofop(dk3_fig_drawing_t *drw, int val) { if(drw) { drw->cofop = ((val) ? 1 : 0); } } void dk3fig_set_options_srctype(dk3_fig_drawing_t *drw, int val) { if(drw) { drw->srctype = val; } } void dk3fig_set_options_arrows( dk3_fig_drawing_t *drw, double arcspp, double splspp, size_t minspp ) { if(drw) { drw->arcspp = arcspp; if(drw->arcspp < 2.0) { drw->arcspp = 2.0; } drw->splspp = splspp; if(drw->splspp < 2.0) { drw->splspp = 2.0; } drw->minspp = minspp; if(drw->minspp < 2) { drw->minspp = 2; } } } void dk3fig_set_options_iteration_precision( dk3_fig_drawing_t *drw, double prec ) { if(drw) { drw->xsprec = fabs(prec); if(drw->xsprec < 1.0e-24) { drw->xsprec = 1.0e-24; } } } void dk3fig_gs_init(dk3_graphics_state_t *gs) { if(gs) { (gs->c1).r = (gs->c1).g = (gs->c1).b = 0.0; (gs->c2).r = (gs->c2).g = (gs->c2).b = 0.0; gs->lw = -1.0; gs->sv = -1.0; gs->slw = -1.0; gs->lc = gs->lj = gs->ls = 0; gs->hc1 = gs->hc2 = gs->hlc = gs->hlj = gs->hlw = gs->hls = 0; gs->hfn = 0; gs->fs = -1.0; gs->fn = -1; } } void dk3fig_set_options_codi( dk3_fig_drawing_t *drw, size_t codi ) { if(drw) { drw->codi = codi; } } void dk3fig_set_ec(dk3_fig_drawing_t *drw, int ec) { if(drw) { if(0 == drw->ec) { drw->ec = ec; } } }