metafile-print.cpp revision 1710c8729db34263e50b443e7fcf541d3cffa005
/** @file
* @brief Metafile printing - common routines
*//*
* Authors:
* Krzysztof KosiĆski <tweenk.pl@gmail.com>
*
* Copyright (C) 2013 Authors
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <cstring>
#include <fstream>
#include <glib.h>
#include <glibmm/miscutils.h>
#include "extension/internal/metafile-print.h"
#include "path-prefix.h"
#include "sp-gradient.h"
#include "sp-image.h"
#include "sp-linear-gradient.h"
#include "sp-pattern.h"
#include "sp-radial-gradient.h"
#include "style.h"
namespace Inkscape {
namespace Extension {
namespace Internal {
bool PrintMetafile::_ppt_fontfix_read = false;
{
#ifndef G_OS_WIN32
// restore default signal handling for SIGPIPE
#endif
return;
}
{
}
unsigned int PrintMetafile::bind(Inkscape::Extension::Print * /*mod*/, Geom::Affine const &transform, float /*opacity*/)
{
if (!m_tr_stack.empty()) {
} else {
}
return 1;
}
{
m_tr_stack.pop();
return 1;
}
{
static bool ppt_fontfix_available = false;
if (_ppt_fontfix_read) return ppt_fontfix_available;
_ppt_fontfix_read = true;
// add default entry
if (!fontfix_file.is_open()) {
g_warning("Unable to open PowerPoint fontfix file: %s\n"
fontfix_path.c_str());
return (ppt_fontfix_available = false);
}
if (instr[0] == '#') {
continue;
}
// not a comment, get the 4 values from the line
char fontname[128];
if (elements != 4) {
continue;
}
}
return (ppt_fontfix_available = true);
}
// Finds font fix parameters for the given fontname.
{
if (!_ppt_fontfix_read) _load_ppt_fontfix_data();
if (f != _ppt_fixable_fonts.end()) {
}
}
{
(color >> 0) & 0xFF
);
return out;
}
// Translate Inkscape weights to EMF weights.
{
switch (inkweight) {
// 400 is tested first, as it is the most common case
case SP_CSS_FONT_WEIGHT_400: return U_FW_NORMAL;
case SP_CSS_FONT_WEIGHT_100: return U_FW_THIN;
case SP_CSS_FONT_WEIGHT_200: return U_FW_EXTRALIGHT;
case SP_CSS_FONT_WEIGHT_300: return U_FW_LIGHT;
case SP_CSS_FONT_WEIGHT_500: return U_FW_MEDIUM;
case SP_CSS_FONT_WEIGHT_600: return U_FW_SEMIBOLD;
case SP_CSS_FONT_WEIGHT_700: return U_FW_BOLD;
case SP_CSS_FONT_WEIGHT_800: return U_FW_EXTRABOLD;
case SP_CSS_FONT_WEIGHT_900: return U_FW_HEAVY;
default: return U_FW_NORMAL;
}
}
/* opacity weighting of two colors as float. v1 is the color, op is its opacity, v2 is the background color */
{
}
{
if (last >= 1) {
float rgbs[3];
float rgbe[3];
/* Replace opacity at start & stop with that fraction background color, then average those two for final color. */
);
} else {
}
return cr;
}
#define clrweight(a,b,t) ((1-t)*((double) a) + (t)*((double) b))
{
);
return result;
}
{
// now handle the opacity, mix the RGB with background at the weighted opacity
}
return result;
}
// Extract hatchType, hatchColor from a name like
// EMFhatch<hatchType>_<hatchColor>
// Where the first one is a number and the second a color in hex.
// hatchType and hatchColor have been set with defaults before this is called.
//
void PrintMetafile::hatch_classify(char *name, int *hatchType, U_COLORREF *hatchColor, U_COLORREF *bkColor)
{
int val;
// name should be EMFhatch or WMFhatch but *MFhatch will be accepted
return; // not anything we can parse
}
val = 0;
name++;
}
*hatchType = -1;
} else {
name++;
}
} else {
usebk = true;
}
}
/* Everything > U_HS_SOLIDCLR is solid, just specify the color in the brush rather than messing around with background or textcolor */
if (*hatchType > U_HS_SOLIDCLR) {
}
}
//
// Recurse down from a brush pattern, try to figure out what it is.
// If an image is found set a pointer to the epixbuf, else set that to NULL
// If a pattern is found with a name like [EW]MFhatch3_3F7FFF return hatchType=3, hatchColor=3F7FFF (as a uint32_t),
// otherwise hatchType is set to -1 and hatchColor is not defined.
//
void PrintMetafile::brush_classify(SPObject *parent, int depth, GdkPixbuf **epixbuf, int *hatchType, U_COLORREF *hatchColor, U_COLORREF *bkColor)
{
if (depth == 0) {
*hatchType = -1;
*hatchColor = U_RGB(0, 0, 0);
}
depth++;
// first look along the pattern chain, if there is one
if (SP_IS_PATTERN(parent)) {
for (SPPattern *pat_i = SP_PATTERN(parent); pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (SP_IS_IMAGE(pat_i)) {
return;
}
if (*hatchType != -1) {
return;
}
// still looking? Look at this pattern's children, if there are any
}
}
} else if (SP_IS_IMAGE(parent)) {
return;
} else { // some inkscape rearrangements pass through nodes between pattern and image which are not classified as either.
}
}
}
//swap R/B in 4 byte pixel
{
char tmp;
}
}
{
if (mode == DRAW_RADIAL_GRADIENT) {
if (rg->gradientTransform_set) {
}
} else if (mode == DRAW_LINEAR_GRADIENT) {
gv.r = 0; // unused
if (lg->gradientTransform_set) {
}
} else {
g_error("Fatal programming error, hold_gradient() in metafile-print.cpp called with invalid draw mode");
}
return 1;
}
/* convert from center ellipse to SVGEllipticalArc ellipse
From:
http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
A point (x,y) on the arc can be found by:
{x,y} = {cx,cy} + {cosF,-sinF,sinF,cosF} x {rxcosT,rysinT}
where
{cx,cy} is the center of the ellipse
F is the rotation angle of the X axis of the ellipse from the true X axis
T is the rotation angle around the ellipse
{,,,} is the rotation matrix
rx,ry are the radii of the ellipse's axes
For SVG parameterization need two points.
Arbitrarily we can use T=0 and T=pi
Since the sweep is 180 the flags are always 0:
F is in RADIANS, but the SVGEllipticalArc needs degrees!
*/
Geom::PathVector PrintMetafile::center_ellipse_as_SVG_PathV(Geom::Point ctr, double rx, double ry, double F)
{
using Geom::X;
using Geom::Y;
char text[256];
sprintf(text, " M %f,%f A %f %f %f 0 0 %f %f A %f %f %f 0 0 %f %f z", x1, y1, rx, ry, F * 360. / (2.*M_PI), x2, y2, rx, ry, F * 360. / (2.*M_PI), x1, y1);
return outres;
}
/* rx2,ry2 must be larger than rx1,ry1!
angle is in RADIANS
*/
Geom::PathVector PrintMetafile::center_elliptical_ring_as_SVG_PathV(Geom::Point ctr, double rx1, double ry1, double rx2, double ry2, double F)
{
using Geom::X;
using Geom::Y;
char text[512];
sprintf(text, " M %f,%f A %f %f %f 0 1 %f %f A %f %f %f 0 1 %f %f z M %f,%f A %f %f %f 0 0 %f %f A %f %f %f 0 0 %f %f z",
return outres;
}
/* Elliptical hole in a large square extending from -50k to +50k */
Geom::PathVector PrintMetafile::center_elliptical_hole_as_SVG_PathV(Geom::Point ctr, double rx, double ry, double F)
{
using Geom::X;
using Geom::Y;
char text[256];
sprintf(text, " M %f,%f A %f %f %f 0 0 %f %f A %f %f %f 0 0 %f %f z M 50000,50000 50000,-50000 -50000,-50000 -50000,50000 z",
return outres;
}
/* rectangular cutter.
ctr "center" of rectangle (might not actually be in the center with respect to leading/trailing edges
pos vector from center to leading edge
neg vector from center to trailing edge
width vector to side edge
*/
Geom::PathVector PrintMetafile::rect_cutter(Geom::Point ctr, Geom::Point pos, Geom::Point neg, Geom::Point width)
{
return outres;
}
/* Convert from SPWindRule to livarot's FillRule
This is similar to what sp_selected_path_boolop() does
*/
{
if (wr == SP_WIND_RULE_EVENODD) {
fr = fill_oddEven;
} else {
fr = fill_nonZero;
}
return fr;
}
} // namespace Internal
} // namespace Extension
} // namespace Inkscape
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :