Compare commits

..

15 Commits

210 changed files with 4154 additions and 39774 deletions

View File

@ -4,7 +4,6 @@ CORE_BOOST_LIBS = $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX/lib
core_ios:CONFIG += disable_enum_constexpr_conversion
core_android:CONFIG += disable_enum_constexpr_conversion
core_mac:CONFIG += disable_enum_constexpr_conversion
core_linux_clang:CONFIG += disable_enum_constexpr_conversion
core_android {
INCLUDEPATH += $$PWD/build/android/include

View File

@ -1,818 +0,0 @@
// https://android.googlesource.com/platform/external/harfbuzz/+/ics-mr0/contrib/tables/script-properties.h
/*
* https://unicode.org/reports/tr29/
As far as a user is concerned, the underlying representation of text is not important,
but it is important that an editing interface present a uniform implementation of what
the user thinks of as characters. Grapheme clusters can be treated as units, by default,
for processes such as the formatting of drop caps, as well as the implementation of text
selection, arrow key movement or backspacing through text, and so forth. For example,
when a grapheme cluster is represented internally by a character sequence consisting of
base character + accents, then using the right arrow key would skip from the start of the
base character to the end of the last accent.
This document defines a default specification for grapheme clusters. It may be customized
for particular languages, operations, or other situations. For example, arrow key movement
could be tailored by language, or could use knowledge specific to particular fonts to move
in a more granular manner, in circumstances where it would be useful to edit individual
components. This could apply, for example, to the complex editorial requirements for the
Northern Thai script Tai Tham (Lanna). Similarly, editing a grapheme cluster element by
element may be preferable in some circumstances. For example, on a given system the backspace
key might delete by code point, while the delete key may delete an entire cluster.
* */
#include "../../../core/DesktopEditor/common/File.h"
#include "../../../core/DesktopEditor/raster/BgraFrame.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_OUTLINE_H
#include <hb-ft.h>
#include <hb-ot.h>
#include <hb.h>
class CDrawer
{
public:
CBgraFrame m_oFrame;
BYTE *pixels;
int width;
int height;
int pitch;
BYTE Rshift;
BYTE Gshift;
BYTE Bshift;
BYTE Ashift;
public:
CDrawer(int w, int h)
{
width = w;
height = h;
pitch = 4 * width;
m_oFrame.put_Width(width);
m_oFrame.put_Height(height);
m_oFrame.put_Stride(pitch);
int size = 4 * width * height;
BYTE *pPixels = new BYTE[size];
for (int i = 0; i < size; i += 4)
{
pPixels[i] = 0xFF;
pPixels[i + 1] = 0xFF;
pPixels[i + 2] = 0xFF;
pPixels[i + 3] = 0xFF;
}
pixels = pPixels;
m_oFrame.put_Data(pPixels);
Bshift = 24;
Gshift = 16;
Rshift = 8;
Ashift = 0;
}
void Save()
{
m_oFrame.SaveFile(NSFile::GetProcessDirectory() + L"/output.png", 4);
}
};
#define NUM_EXAMPLES 3
/* fonts */
const char *fonts_paths[NUM_EXAMPLES] = {
"C:/Windows/Fonts/calibri.ttf",
//"C:/Windows/Fonts/arial.ttf",
"C:/Users/korol/AppData/Local/Microsoft/Windows/Fonts/ArabicTest.ttf",
"C:/Windows/Fonts/simsun.ttc"
};
#define NUM_GLYPH_TYPES 5
const char *num_glyph_types[NUM_GLYPH_TYPES] = {"UNCLASSIFIED", "BASE_GLYPH", "LIGATURE", "MARK", "COMPONENT"};
/* tranlations courtesy of google */
const char *texts[NUM_EXAMPLES] = {
"fi",
"لا لآ لأ لا",
"懶惰的姜貓"
};
const hb_direction_t text_directions[NUM_EXAMPLES] = {
HB_DIRECTION_LTR,
HB_DIRECTION_RTL,
HB_DIRECTION_TTB,
};
const int text_skip[NUM_EXAMPLES] = {
0,
0,
1,
};
/* XXX: These are not correct, though it doesn't seem to break anything
* regardless of their value. */
const char *languages[NUM_EXAMPLES] = {
"en",
"ar",
"ch",
};
const hb_script_t scripts[NUM_EXAMPLES] = {
HB_SCRIPT_LATIN,
HB_SCRIPT_ARABIC,
HB_SCRIPT_HAN,
};
enum
{
ENGLISH = 0,
ARABIC,
CHINESE
};
typedef struct _spanner_baton_t
{
/* rendering part - assumes 32bpp surface */
uint32_t *pixels; // set to the glyph's origin.
uint32_t *first_pixel, *last_pixel; // bounds check
uint32_t pitch;
uint32_t rshift;
uint32_t gshift;
uint32_t bshift;
uint32_t ashift;
/* sizing part */
int min_span_x;
int max_span_x;
int min_y;
int max_y;
} spanner_baton_t;
/* This spanner is write only, suitable for write-only mapped buffers,
but can cause dark streaks where glyphs overlap, like in arabic scripts.
Note how spanners don't clip against surface width - resize the window
and see what it leads to. */
void spanner_wo(int y, int count, const FT_Span *spans, void *user)
{
spanner_baton_t *baton = (spanner_baton_t *)user;
uint32_t *scanline = baton->pixels - y * ((int)baton->pitch / 4);
if (scanline < baton->first_pixel)
return;
for (int i = 0; i < count; i++)
{
uint32_t color = ((spans[i].coverage / 2) << baton->rshift) | ((spans[i].coverage / 2) << baton->gshift) | ((spans[i].coverage / 2) << baton->bshift);
uint32_t *start = scanline + spans[i].x;
if (start + spans[i].len > baton->last_pixel)
return;
for (int x = 0; x < spans[i].len; x++)
*start++ = color;
}
}
/* This spanner does read/modify/write, trading performance for accuracy.
The color here is simply half coverage value in all channels,
effectively mid-gray.
Suitable for when artifacts mostly do come up and annoy.
This might be optimized if one does rmw only for some values of x.
But since the whole buffer has to be rw anyway, and the previous value
is probably still in the cache, there's little point to. */
void spanner_rw(int y, int count, const FT_Span *spans, void *user)
{
spanner_baton_t *baton = (spanner_baton_t *)user;
uint32_t *scanline = baton->pixels - y * ((int)baton->pitch / 4);
if (scanline < baton->first_pixel)
return;
for (int i = 0; i < count; i++)
{
uint32_t color = ((spans[i].coverage / 2) << baton->rshift) | ((spans[i].coverage / 2) << baton->gshift) | ((spans[i].coverage / 2) << baton->bshift);
uint32_t *start = scanline + spans[i].x;
if (start + spans[i].len > baton->last_pixel)
return;
for (int x = 0; x < spans[i].len; x++)
*start++ |= color;
}
}
/* This spanner is for obtaining exact bounding box for the string.
Unfortunately this can't be done without rendering it (or pretending to).
After this runs, we get min and max values of coordinates used.
*/
void spanner_sizer(int y, int count, const FT_Span *spans, void *user)
{
spanner_baton_t *baton = (spanner_baton_t *)user;
if (y < baton->min_y)
baton->min_y = y;
if (y > baton->max_y)
baton->max_y = y;
for (int i = 0; i < count; i++)
{
if (spans[i].x + spans[i].len > baton->max_span_x)
baton->max_span_x = spans[i].x + spans[i].len;
if (spans[i].x < baton->min_span_x)
baton->min_span_x = spans[i].x;
}
}
FT_SpanFunc spanner = spanner_wo;
void ftfdump(FT_Face ftf)
{
for (int i = 0; i < ftf->num_charmaps; i++)
{
printf(
"%d: %s %s %c%c%c%c plat=%hu id=%hu\n", i, ftf->family_name, ftf->style_name, ftf->charmaps[i]->encoding >> 24, (ftf->charmaps[i]->encoding >> 16) & 0xff,
(ftf->charmaps[i]->encoding >> 8) & 0xff, (ftf->charmaps[i]->encoding) & 0xff, ftf->charmaps[i]->platform_id, ftf->charmaps[i]->encoding_id);
}
}
/* See http://www.microsoft.com/typography/otspec/name.htm
for a list of some possible platform-encoding pairs.
We're interested in 0-3 aka 3-1 - UCS-2.
Otherwise, fail. If a font has some unicode map, but lacks
UCS-2 - it is a broken or irrelevant font. What exactly
Freetype will select on face load (it promises most wide
unicode, and if that will be slower that UCS-2 - left as
an excercise to check. */
int force_ucs2_charmap(FT_Face ftf)
{
for (int i = 0; i < ftf->num_charmaps; i++)
if (((ftf->charmaps[i]->platform_id == 0) && (ftf->charmaps[i]->encoding_id == 3)) || ((ftf->charmaps[i]->platform_id == 3) && (ftf->charmaps[i]->encoding_id == 1)))
return FT_Set_Charmap(ftf, ftf->charmaps[i]);
return -1;
}
void hline(CDrawer *s, int min_x, int max_x, int y, uint32_t color)
{
if (y < 0)
y = 0;
uint32_t *pix = (uint32_t *)s->pixels + (y * s->pitch) / 4 + min_x;
uint32_t *end = (uint32_t *)s->pixels + (y * s->pitch) / 4 + max_x;
while (pix - 1 != end)
*pix++ = color;
}
void vline(CDrawer *s, int min_y, int max_y, int x, uint32_t color)
{
if (min_y < 0)
min_y = 0;
uint32_t *pix = (uint32_t *)s->pixels + (min_y * s->pitch) / 4 + x;
uint32_t *end = (uint32_t *)s->pixels + (max_y * s->pitch) / 4 + x;
while (pix - s->pitch / 4 != end)
{
*pix = color;
pix += s->pitch / 4;
}
}
void assert(const bool &valid)
{
// TODO:
}
#define MAIN_CC_NO_PRIVATE_API
#ifndef MAIN_CC_NO_PRIVATE_API
/* Only this part of this mini app uses private API */
#include "hb-open-file.hh"
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsubgpos.hh"
#include "hb-static.cc"
using namespace OT;
static void print_layout_info_using_private_api(hb_blob_t *blob)
{
const char *font_data = hb_blob_get_data(blob, nullptr);
hb_blob_t *font_blob = hb_sanitize_context_t().sanitize_blob<OpenTypeFontFile>(blob);
const OpenTypeFontFile *sanitized = font_blob->as<OpenTypeFontFile>();
if (!font_blob->data)
{
printf("Sanitization of the file wasn't successful. Exit");
exit(1);
}
const OpenTypeFontFile &ot = *sanitized;
switch (ot.get_tag())
{
case OpenTypeFontFile::TrueTypeTag:
printf("OpenType font with TrueType outlines\n");
break;
case OpenTypeFontFile::CFFTag:
printf("OpenType font with CFF (Type1) outlines\n");
break;
case OpenTypeFontFile::TTCTag:
printf("TrueType Collection of OpenType fonts\n");
break;
case OpenTypeFontFile::TrueTag:
printf("Obsolete Apple TrueType font\n");
break;
case OpenTypeFontFile::Typ1Tag:
printf("Obsolete Apple Type1 font in SFNT container\n");
break;
case OpenTypeFontFile::DFontTag:
printf("DFont Mac Resource Fork\n");
break;
default:
printf("Unknown font format\n");
break;
}
unsigned num_faces = hb_face_count(blob);
printf("%d font(s) found in file\n", num_faces);
for (unsigned n_font = 0; n_font < num_faces; ++n_font)
{
const OpenTypeFontFace &font = ot.get_face(n_font);
printf("Font %d of %d:\n", n_font, num_faces);
unsigned num_tables = font.get_table_count();
printf(" %d table(s) found in font\n", num_tables);
for (unsigned n_table = 0; n_table < num_tables; ++n_table)
{
const OpenTypeTable &table = font.get_table(n_table);
printf(" Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table, num_tables, (const char *)table.tag, (unsigned)table.offset, (unsigned)table.length);
switch (table.tag)
{
case HB_OT_TAG_GSUB:
case HB_OT_TAG_GPOS:
{
const GSUBGPOS &g = *reinterpret_cast<const GSUBGPOS *>(font_data + table.offset);
unsigned num_scripts = g.get_script_count();
printf(" %d script(s) found in table\n", num_scripts);
for (unsigned n_script = 0; n_script < num_scripts; ++n_script)
{
const Script &script = g.get_script(n_script);
printf(" Script %2d of %2d: %.4s\n", n_script, num_scripts, (const char *)g.get_script_tag(n_script));
if (!script.has_default_lang_sys())
printf(" No default language system\n");
int num_langsys = script.get_lang_sys_count();
printf(" %d language system(s) found in script\n", num_langsys);
for (int n_langsys = script.has_default_lang_sys() ? -1 : 0; n_langsys < num_langsys; ++n_langsys)
{
const LangSys &langsys = n_langsys == -1 ? script.get_default_lang_sys() : script.get_lang_sys(n_langsys);
if (n_langsys == -1)
printf(" Default Language System\n");
else
printf(" Language System %2d of %2d: %.4s\n", n_langsys, num_langsys, (const char *)script.get_lang_sys_tag(n_langsys));
if (!langsys.has_required_feature())
printf(" No required feature\n");
else
printf(" Required feature index: %d\n", langsys.get_required_feature_index());
unsigned num_features = langsys.get_feature_count();
printf(" %d feature(s) found in language system\n", num_features);
for (unsigned n_feature = 0; n_feature < num_features; ++n_feature)
{
printf(" Feature index %2d of %2d: %d\n", n_feature, num_features, langsys.get_feature_index(n_feature));
}
}
}
unsigned num_features = g.get_feature_count();
printf(" %d feature(s) found in table\n", num_features);
for (unsigned n_feature = 0; n_feature < num_features; ++n_feature)
{
const Feature &feature = g.get_feature(n_feature);
unsigned num_lookups = feature.get_lookup_count();
printf(" Feature %2d of %2d: %c%c%c%c\n", n_feature, num_features, HB_UNTAG(g.get_feature_tag(n_feature)));
printf(" %d lookup(s) found in feature\n", num_lookups);
for (unsigned n_lookup = 0; n_lookup < num_lookups; ++n_lookup)
{
printf(" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups, feature.get_lookup_index(n_lookup));
}
}
unsigned num_lookups = g.get_lookup_count();
printf(" %d lookup(s) found in table\n", num_lookups);
for (unsigned n_lookup = 0; n_lookup < num_lookups; ++n_lookup)
{
const Lookup &lookup = g.get_lookup(n_lookup);
printf(" Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup, num_lookups, lookup.get_type(), lookup.get_props());
}
}
break;
case GDEF::tableTag:
{
const GDEF &gdef = *reinterpret_cast<const GDEF *>(font_data + table.offset);
printf(" Has %sglyph classes\n", gdef.has_glyph_classes() ? "" : "no ");
printf(" Has %smark attachment types\n", gdef.has_mark_attachment_types() ? "" : "no ");
printf(" Has %sattach points\n", gdef.has_attach_points() ? "" : "no ");
printf(" Has %slig carets\n", gdef.has_lig_carets() ? "" : "no ");
printf(" Has %smark sets\n", gdef.has_mark_sets() ? "" : "no ");
hb_position_t caret_array[16];
unsigned int caret_count = 16;
unsigned int num_carets = gdef.get_lig_carets(nullptr, HB_DIRECTION_LTR, 302, 0, &caret_count, caret_array);
int y = 0;
++y;
break;
}
}
}
}
}
/* end of private API use */
#endif
struct hb_feature_test {
hb_tag_t tag;
uint32_t value;
};
int main(int argc, char *argv[])
{
// hb_blob_t* blobFileTest = hb_blob_create_from_file("C:/Windows/Fonts/calibri.ttf");
// print_layout_info_using_private_api(blobFileTest);
int ptSize = 40 * 64;
int device_hdpi = 72;
int device_vdpi = 72;
/* Init freetype */
FT_Library ft_library;
assert(!FT_Init_FreeType(&ft_library));
/* Load our fonts */
FT_Face ft_face[NUM_EXAMPLES];
assert(!FT_New_Face(ft_library, fonts_paths[0], 0, &ft_face[ENGLISH]));
assert(!FT_Set_Char_Size(ft_face[ENGLISH], 0, ptSize, device_hdpi, device_vdpi));
ftfdump(ft_face[ENGLISH]); // wonderful world of encodings ...
// force_ucs2_charmap(ft_face[ENGLISH]); // which we ignore.
assert(!FT_New_Face(ft_library, fonts_paths[1], 0, &ft_face[ARABIC]));
assert(!FT_Set_Char_Size(ft_face[ARABIC], 0, ptSize, device_hdpi, device_vdpi));
ftfdump(ft_face[ARABIC]);
// force_ucs2_charmap(ft_face[ARABIC]);
assert(!FT_New_Face(ft_library, fonts_paths[2], 0, &ft_face[CHINESE]));
assert(!FT_Set_Char_Size(ft_face[CHINESE], 0, ptSize, device_hdpi, device_vdpi));
ftfdump(ft_face[CHINESE]);
// force_ucs2_charmap(ft_face[CHINESE]);
/* Get our harfbuzz font structs */
hb_font_t *hb_ft_font[NUM_EXAMPLES];
hb_ft_font[ENGLISH] = hb_ft_font_create(ft_face[ENGLISH], NULL);
// hb_blob_t* blobFile = hb_blob_create_from_file(sFont1.c_str());
// hb_face_t* faceFile = hb_face_create(blobFile, 0);
// hb_ft_font[ENGLISH] = hb_font_create(faceFile);
hb_ft_font[ARABIC] = hb_ft_font_create(ft_face[ARABIC], NULL);
hb_ft_font[CHINESE] = hb_ft_font_create(ft_face[CHINESE], NULL);
hb_ft_font_set_funcs(hb_ft_font[ENGLISH]);
hb_ft_font_set_funcs(hb_ft_font[ARABIC]);
hb_ft_font_set_funcs(hb_ft_font[CHINESE]);
/** Setup our SDL window **/
int width = 800;
int height = 600;
int bpp = 32;
CDrawer oDrawer(width, height);
/* Create a buffer for harfbuzz to use */
hb_buffer_t *buf = hb_buffer_create();
for (int i = 0; i < NUM_EXAMPLES; ++i)
{
if (text_skip[i])
continue;
hb_buffer_set_direction(buf, text_directions[i]); /* or LTR */
hb_buffer_set_script(buf, scripts[i]); /* see hb-unicode.h */
hb_buffer_set_language(buf, hb_language_from_string(languages[i], strlen(languages[i])));
// hb_buffer_set_cluster_level (buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES);
// hb_buffer_set_cluster_level (buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
hb_buffer_set_cluster_level(buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES);
hb_feature_test features[] {
{HB_TAG('r','l','i','g'), 1},
{HB_TAG('l','i','g','a'), 0},
{HB_TAG('c','l','i','g'), 1},
{HB_TAG('h','l','i','g'), 1},
{HB_TAG('d','l','i','g'), 1},
{HB_TAG('k','e','r','n'), 2},
{0, 0}
};
int userfeatures_count = 0;
hb_feature_t userfeatures[100];
hb_feature_test* current_feature = features;
while (current_feature->tag != 0)
{
if (current_feature->value != 2)
{
userfeatures[userfeatures_count].tag = current_feature->tag;
userfeatures[userfeatures_count].value = current_feature->value;
userfeatures[userfeatures_count].start = HB_FEATURE_GLOBAL_START;
userfeatures[userfeatures_count].end = HB_FEATURE_GLOBAL_END;
userfeatures_count++;
}
current_feature++;
}
/* Layout the text */
hb_buffer_add_utf8(buf, texts[i], strlen(texts[i]), 0, strlen(texts[i]));
// detect script by codes
hb_buffer_guess_segment_properties(buf);
// const char*const pHbShapers[] = { "graphite2", "coretext_aat", "ot", "fallback", nullptr };
// bool ok = hb_shape_full(hb_ft_font[i], buf, userfeatures, userfeatures_count, pHbShapers);
hb_shape(hb_ft_font[i], buf, (userfeatures_count != 0) ? userfeatures : NULL, userfeatures_count);
unsigned int glyph_count;
hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count);
hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count);
#if 1
hb_position_t caret_array[16];
unsigned int caret_count = 16;
unsigned int num_carets = hb_ot_layout_get_ligature_carets(hb_ft_font[i], text_directions[i], glyph_info[0].codepoint, -1, &caret_count, caret_array);
#endif
/* set up rendering via spanners */
spanner_baton_t stuffbaton;
FT_Raster_Params ftr_params;
ftr_params.target = 0;
ftr_params.flags = FT_RASTER_FLAG_DIRECT | FT_RASTER_FLAG_AA;
ftr_params.user = &stuffbaton;
ftr_params.black_spans = 0;
ftr_params.bit_set = 0;
ftr_params.bit_test = 0;
/* Calculate string bounding box in pixels */
ftr_params.gray_spans = spanner_sizer;
/* See http://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html */
int max_x = INT_MIN; // largest coordinate a pixel has been set at, or the pen was advanced to.
int min_x = INT_MAX; // smallest coordinate a pixel has been set at, or the pen was advanced to.
int max_y = INT_MIN; // this is max topside bearing along the string.
int min_y = INT_MAX; // this is max value of (height - topbearing) along the string.
/* Naturally, the above comments swap their meaning between horizontal and vertical scripts,
since the pen changes the axis it is advanced along.
However, their differences still make up the bounding box for the string.
Also note that all this is in FT coordinate system where y axis points upwards.
*/
int sizer_x = 0;
int sizer_y = 0; /* in FT coordinate system. */
printf("----------------------------------------------------\n");
for (unsigned j = 0; j < glyph_count; ++j)
{
hb_ot_layout_glyph_class_t glyph_type = hb_ot_layout_get_glyph_class(hb_font_get_face(hb_ft_font[i]), glyph_info[j].codepoint);
hb_glyph_flags_t glyph_type_flags = hb_glyph_info_get_glyph_flags(&glyph_info[j]);
printf(
"glyph(%s, flags: %d): gid:%d, cluster:%d, [%d, %d, %d, %d, %d]\n", num_glyph_types[glyph_type], glyph_type_flags, (int)glyph_info[j].codepoint, (int)glyph_info[j].cluster,
glyph_pos[j].x_advance, glyph_pos[j].y_advance, glyph_pos[j].x_offset, glyph_pos[j].y_offset, glyph_pos[j].var);
}
FT_Error fterr;
for (unsigned j = 0; j < glyph_count; ++j)
{
if ((fterr = FT_Load_Glyph(ft_face[i], glyph_info[j].codepoint, 0)))
{
printf("load %08x failed fterr=%d.\n", glyph_info[j].codepoint, fterr);
}
else
{
if (ft_face[i]->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
{
printf("glyph->format = %4s\n", (char *)&ft_face[i]->glyph->format);
}
else
{
int gx = sizer_x + (glyph_pos[j].x_offset / 64);
int gy = sizer_y + (glyph_pos[j].y_offset / 64); // note how the sign differs from the rendering pass
stuffbaton.min_span_x = INT_MAX;
stuffbaton.max_span_x = INT_MIN;
stuffbaton.min_y = INT_MAX;
stuffbaton.max_y = INT_MIN;
if ((fterr = FT_Outline_Render(ft_library, &ft_face[i]->glyph->outline, &ftr_params)))
printf("FT_Outline_Render() failed err=%d\n", fterr);
if (stuffbaton.min_span_x != INT_MAX)
{
/* Update values if the spanner was actually called. */
if (min_x > stuffbaton.min_span_x + gx)
min_x = stuffbaton.min_span_x + gx;
if (max_x < stuffbaton.max_span_x + gx)
max_x = stuffbaton.max_span_x + gx;
if (min_y > stuffbaton.min_y + gy)
min_y = stuffbaton.min_y + gy;
if (max_y < stuffbaton.max_y + gy)
max_y = stuffbaton.max_y + gy;
}
else
{
/* The spanner wasn't called at all - an empty glyph, like space. */
if (min_x > gx)
min_x = gx;
if (max_x < gx)
max_x = gx;
if (min_y > gy)
min_y = gy;
if (max_y < gy)
max_y = gy;
}
}
}
sizer_x += glyph_pos[j].x_advance / 64;
sizer_y += glyph_pos[j].y_advance / 64; // note how the sign differs from the rendering pass
}
/* Still have to take into account last glyph's advance. Or not? */
if (min_x > sizer_x)
min_x = sizer_x;
if (max_x < sizer_x)
max_x = sizer_x;
if (min_y > sizer_y)
min_y = sizer_y;
if (max_y < sizer_y)
max_y = sizer_y;
/* The bounding box */
int bbox_w = max_x - min_x;
int bbox_h = max_y - min_y;
/* Two offsets below position the bounding box with respect to the 'origin',
which is sort of origin of string's first glyph.
baseline_offset - offset perpendecular to the baseline to the topmost (horizontal),
or leftmost (vertical) pixel drawn.
baseline_shift - offset along the baseline, from the first drawn glyph's origin
to the leftmost (horizontal), or topmost (vertical) pixel drawn.
Thus those offsets allow positioning the bounding box to fit the rendered string,
as they are in fact offsets from the point given to the renderer, to the top left
corner of the bounding box.
NB: baseline is defined as y==0 for horizontal and x==0 for vertical scripts.
(0,0) here is where the first glyph's origin ended up after shaping, not taking
into account glyph_pos[0].xy_offset (yeah, my head hurts too).
*/
int baseline_offset;
int baseline_shift;
if (HB_DIRECTION_IS_HORIZONTAL(hb_buffer_get_direction(buf)))
{
baseline_offset = max_y;
baseline_shift = min_x;
}
if (HB_DIRECTION_IS_VERTICAL(hb_buffer_get_direction(buf)))
{
baseline_offset = min_x;
baseline_shift = max_y;
}
/* The pen/baseline start coordinates in window coordinate system
- with those text placement in the window is controlled.
- note that for RTL scripts pen still goes LTR */
int x = 0, y = 50 + i * 75;
if (i == ENGLISH)
{
x = 20;
} /* left justify */
if (i == ARABIC)
{
x = width - bbox_w - 20;
} /* right justify */
if (i == CHINESE)
{
x = width / 2 - bbox_w / 2;
} /* center, and for TTB script h_advance is half-width. */
/* Draw baseline and the bounding box */
/* The below is complicated since we simultaneously
convert to the window coordinate system. */
int left, right, top, bottom;
if (HB_DIRECTION_IS_HORIZONTAL(hb_buffer_get_direction(buf)))
{
/* bounding box in window coordinates without offsets */
left = x;
right = x + bbox_w;
top = y - bbox_h;
bottom = y;
/* apply offsets */
left += baseline_shift;
right += baseline_shift;
top -= baseline_offset - bbox_h;
bottom -= baseline_offset - bbox_h;
/* draw the baseline */
hline(&oDrawer, x, x + bbox_w, y, 0x0000ff00);
}
if (HB_DIRECTION_IS_VERTICAL(hb_buffer_get_direction(buf)))
{
left = x;
right = x + bbox_w;
top = y;
bottom = y + bbox_h;
left += baseline_offset;
right += baseline_offset;
top -= baseline_shift;
bottom -= baseline_shift;
vline(&oDrawer, y, y + bbox_h, x, 0x0000ff00);
}
/* +1/-1 are for the bbox borders be the next pixel outside the bbox itself */
hline(&oDrawer, left - 1, right + 1, top - 1, 0xffff0000);
hline(&oDrawer, left - 1, right + 1, bottom + 1, 0xffff0000);
vline(&oDrawer, top - 1, bottom + 1, left - 1, 0xffff0000);
vline(&oDrawer, top - 1, bottom + 1, right + 1, 0xffff0000);
/* set rendering spanner */
ftr_params.gray_spans = spanner;
/* initialize rendering part of the baton */
stuffbaton.pixels = NULL;
stuffbaton.first_pixel = (uint32_t *)oDrawer.pixels;
stuffbaton.last_pixel = (uint32_t *)(((uint8_t *)oDrawer.pixels) + oDrawer.pitch * oDrawer.height);
stuffbaton.pitch = oDrawer.pitch;
stuffbaton.rshift = oDrawer.Rshift;
stuffbaton.gshift = oDrawer.Gshift;
stuffbaton.bshift = oDrawer.Bshift;
/* render */
for (unsigned j = 0; j < glyph_count; ++j)
{
if ((fterr = FT_Load_Glyph(ft_face[i], glyph_info[j].codepoint, 0)))
{
printf("load %08x failed fterr=%d.\n", glyph_info[j].codepoint, fterr);
}
else
{
if (ft_face[i]->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
{
printf("glyph->format = %4s\n", (char *)&ft_face[i]->glyph->format);
}
else
{
int gx = x + (glyph_pos[j].x_offset / 64);
int gy = y - (glyph_pos[j].y_offset / 64);
stuffbaton.pixels = (uint32_t *)(((uint8_t *)oDrawer.pixels) + gy * oDrawer.pitch) + gx;
if ((fterr = FT_Outline_Render(ft_library, &ft_face[i]->glyph->outline, &ftr_params)))
printf("FT_Outline_Render() failed err=%d\n", fterr);
}
}
x += glyph_pos[j].x_advance / 64;
y -= glyph_pos[j].y_advance / 64;
}
/* clean up the buffer, but don't kill it just yet */
hb_buffer_clear_contents(buf);
}
/* Cleanup */
hb_buffer_destroy(buf);
for (int i = 0; i < NUM_EXAMPLES; ++i)
hb_font_destroy(hb_ft_font[i]);
FT_Done_FreeType(ft_library);
oDrawer.Save();
return 0;
}

View File

@ -1,19 +0,0 @@
CONFIG -= qt
TARGET = test
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CORE_ROOT_DIR = $$PWD/../../../../../core
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
include($$CORE_ROOT_DIR/DesktopEditor/graphics/pro/freetype.pri)
include($$CORE_ROOT_DIR/Common/3dParty/harfbuzz/harfbuzz.pri)
SOURCES += main.cpp
ADD_DEPENDENCY(UnicodeConverter, kernel, graphics)
DESTDIR = $$PWD/build

View File

@ -25,5 +25,3 @@ if not base.is_dir("katana-parser"):
base.replaceInFileUtf8(base_directory + "/katana-parser/src/tokenizer.c", "static inline bool2 katana_is_html_space(char c);", "static inline bool katana_is_html_space(char c);")
base.replaceInFileUtf8(base_directory + "/katana-parser/src/parser.c", "katanaget_text(parser->scanner)", "/*katanaget_text(parser->scanner)*/\"error\"")
base.replaceInFileUtf8(base_directory + "/katana-parser/src/parser.c", "#define KATANA_PARSER_STRING(literal) (KatanaParserString){", "#define KATANA_PARSER_STRING(literal) {")
# katana may not be able to handle an empty string correctly in some cases (bug#73485)
base.replaceInFileUtf8(base_directory + "/katana-parser/src/foundation.c", "size_t len = strlen(str);", "if (NULL == str)\n return;\n size_t len = strlen(str);")

View File

@ -19,6 +19,7 @@ static std::string nonbreaking_inline = "|a|abbr|acronym|b|bdo|big|cite|code|df
static std::string empty_tags = "|area|base|basefont|bgsound|br|command|col|embed|event-source|frame|hr|image|img|input|keygen|link|menuitem|meta|param|source|spacer|track|wbr|";
static std::string preserve_whitespace = "|pre|textarea|script|style|";
static std::string special_handling = "|html|body|";
static std::string no_entity_sub = ""; //"|style|";
static std::string treat_like_inline = "|p|";
static std::vector<std::string> html_tags = {"div","span","a","img","p","h1","h2","h3","h4","h5","h6",
@ -435,25 +436,9 @@ static void substitute_xml_entities_into_text(std::string& text)
replace_all(text, ">", "&gt;");
}
// After running through Gumbo, the values of type "&#1;" are replaced with the corresponding code '0x01'
// Since the attribute value does not use control characters (value <= 0x1F),
// then just delete them, otherwise XmlUtils::CXmlLiteReader crashes on them.
// bug#73486
static void remove_control_symbols(std::string& text)
{
std::string::iterator itFound = std::find_if(text.begin(), text.end(), [](char chValue){ return chValue <= 0x1F; });
while (itFound != text.end())
{
itFound = text.erase(itFound);
itFound = std::find_if(itFound, text.end(), [](char chValue){ return chValue <= 0x1F; });
}
}
// Заменяет сущности " в text
static void substitute_xml_entities_into_attributes(std::string& text)
{
remove_control_symbols(text);
substitute_xml_entities_into_text(text);
replace_all(text, "\"", "&quot;");
}
@ -501,7 +486,7 @@ static void build_doctype(GumboNode* node, NSStringUtils::CStringBuilderA& oBuil
}
}
static void build_attributes(const GumboVector* attribs, NSStringUtils::CStringBuilderA& atts)
static void build_attributes(const GumboVector* attribs, bool no_entities, NSStringUtils::CStringBuilderA& atts)
{
std::vector<std::string> arrRepeat;
for (size_t i = 0; i < attribs->length; ++i)
@ -547,7 +532,8 @@ static void build_attributes(const GumboVector* attribs, NSStringUtils::CStringB
std::string qs ="\"";
atts.WriteString("=");
atts.WriteString(qs);
substitute_xml_entities_into_attributes(sVal);
if(!no_entities)
substitute_xml_entities_into_attributes(sVal);
atts.WriteString(sVal);
atts.WriteString(qs);
}
@ -556,6 +542,7 @@ static void build_attributes(const GumboVector* attribs, NSStringUtils::CStringB
static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents, bool bCheckValidNode)
{
std::string key = "|" + get_tag_name(node) + "|";
bool no_entity_substitution = no_entity_sub.find(key) != std::string::npos;
bool keep_whitespace = preserve_whitespace.find(key) != std::string::npos;
bool is_inline = nonbreaking_inline.find(key) != std::string::npos;
bool is_like_inline = treat_like_inline.find(key) != std::string::npos;
@ -569,7 +556,8 @@ static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA
if (child->type == GUMBO_NODE_TEXT)
{
std::string val(child->v.text.text);
substitute_xml_entities_into_text(val);
if(!no_entity_substitution)
substitute_xml_entities_into_text(val);
// Избавление от FF
size_t found = val.find_first_of("\014");
@ -625,6 +613,7 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde
std::string closeTag = "";
std::string key = "|" + tagname + "|";
bool is_empty_tag = empty_tags.find(key) != std::string::npos;
bool no_entity_substitution = no_entity_sub.find(key) != std::string::npos;
// determine closing tag type
if (is_empty_tag)
@ -637,7 +626,7 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde
// build attr string
const GumboVector* attribs = &node->v.element.attributes;
build_attributes(attribs, oBuilder);
build_attributes(attribs, no_entity_substitution, oBuilder);
oBuilder.WriteString(close + ">");
// prettyprint your contents

View File

@ -103,7 +103,6 @@ public:
bool isBinaryDoctFormatFile(unsigned char* pBuffer, int dwBytes);
bool isBinaryXlstFormatFile(unsigned char* pBuffer, int dwBytes);
bool isBinaryPpttFormatFile(unsigned char* pBuffer, int dwBytes);
bool isBinaryVsdtFormatFile(unsigned char* pBuffer, int dwBytes);
bool isDjvuFormatFile(unsigned char* pBuffer, int dwBytes);
bool isMobiFormatFile(unsigned char* pBuffer, int dwBytes);

View File

@ -44,7 +44,6 @@
#include "3dParty/pole/pole.h"
#include <algorithm>
#include <limits>
#include "OfficeFileFormatDefines.h"
@ -223,16 +222,6 @@ bool COfficeFileFormatChecker::isBinaryPpttFormatFile(unsigned char *pBuffer, in
return false;
}
bool COfficeFileFormatChecker::isBinaryVsdtFormatFile(unsigned char* pBuffer, int dwBytes)
{
if (pBuffer == NULL)
return false;
if ((4 <= dwBytes) && ('V' == pBuffer[0] && 'S' == pBuffer[1] && 'D' == pBuffer[2] && 'Y' == pBuffer[3]))
return true;
return false;
}
bool COfficeFileFormatChecker::isPdfFormatFile(unsigned char *pBuffer, int dwBytes, std::wstring &documentID)
{
if (pBuffer == NULL)
@ -827,10 +816,6 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName)
{
nFileType = AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION;
}
else if (isBinaryVsdtFormatFile(bufferDetect, sizeRead)) // min size - 4
{
nFileType = AVS_OFFICESTUDIO_FILE_CANVAS_DRAW;
}
else if (isOOXFlatFormatFile(bufferDetect, sizeRead))
{
// nFileType;
@ -1165,10 +1150,6 @@ bool COfficeFileFormatChecker::isOnlyOfficeFormatFile(const std::wstring &fileNa
{
nFileType = AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY;
}
else if (isBinaryVsdtFormatFile(pBuffer, nBufferSize))
{
nFileType = AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY;
}
delete[] pBuffer;
pBuffer = NULL;
@ -1178,222 +1159,58 @@ bool COfficeFileFormatChecker::isOnlyOfficeFormatFile(const std::wstring &fileNa
}
return false;
}
struct TIWAField
{
size_t m_unStart;
size_t m_unEnd;
unsigned m_uIndex;
unsigned m_unWireType;
uint64_t m_oValue;
};
bool ReadUVar(BYTE* pBuffer, size_t unEndPos, size_t& unPos, uint64_t& unValue)
{
std::vector<unsigned char> arBytes;
arBytes.reserve(8);
unValue = 0;
bool bNext = true;
while (unPos < unEndPos && bNext)
{
const unsigned char c = pBuffer[unPos++];
arBytes.push_back((unsigned char)(c & ~0x80));
bNext = c & 0x80;
}
if (bNext && unPos == unEndPos)
return false;
for (std::vector<unsigned char>::const_reverse_iterator it = arBytes.rbegin(); it != arBytes.rend(); ++it)
{
if (std::numeric_limits<uint64_t>::max() >> 7 < unValue ||
std::numeric_limits<uint64_t>::max() - (unValue << 7) < *it) // overflow
return false;
unValue = (unValue << 7) + *it;
}
return true;
}
bool ReadIWAField(BYTE* pBuffer, size_t unEndPos, size_t& unPos, TIWAField& oIWAField)
{
if (NULL == pBuffer || unPos + 2 > unEndPos)
return false;
unsigned uSpec;
uSpec = (unsigned)pBuffer[unPos++];
oIWAField.m_unWireType = uSpec & 0x7;
oIWAField.m_unStart = unPos;
switch (oIWAField.m_unWireType)
{
case 0:
{
if (!ReadUVar(pBuffer, unEndPos, unPos, oIWAField.m_oValue))
return false;
break;
}
case 1:
{
unPos += 4;
break;
}
case 2:
{
uint64_t unLen;
if (!ReadUVar(pBuffer, unEndPos, unPos, unLen) || unPos + unLen > unEndPos)
return false;
oIWAField.m_unStart = unPos;
unPos += unLen;
break;
}
case 5:
{
unPos += 2;
break;
}
default:
return false;
}
oIWAField.m_unEnd = unPos;
oIWAField.m_uIndex = uSpec >> 3;
return true;
}
bool DetectIWorkFormat(const std::wstring& fileName, int &nType)
bool COfficeFileFormatChecker::isMacFormatFile(const std::wstring& fileName)
{
COfficeUtils OfficeUtils(NULL);
ULONG unSize = 0;
ULONG nBufferSize = 0;
BYTE* pBuffer = NULL;
HRESULT hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Document.iwa", &pBuffer, unSize);
if (hresult != S_OK || NULL == pBuffer)
return false;
#define CLEAR_BUFFER_AND_RETURN(return_value)\
do{\
delete[] pBuffer;\
return return_value;\
}while(false)
if (unSize < 13)
CLEAR_BUFFER_AND_RETURN(false);
size_t uPos = 6;
for (; uPos < 12; ++uPos)
HRESULT hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Document.iwa", &pBuffer, nBufferSize);
if (hresult == S_OK && pBuffer != NULL)
{
if (0x08 == pBuffer[uPos] && 0x01 == pBuffer[uPos + 1])
{
--uPos;
break;
}
}
if (12 == uPos)
CLEAR_BUFFER_AND_RETURN(false);
uint64_t unHeaderLen;
if (!ReadUVar(pBuffer, unSize, uPos, unHeaderLen))
CLEAR_BUFFER_AND_RETURN(false);
const size_t uStartPos = uPos;
if (unHeaderLen < 8 || unSize < unHeaderLen + uStartPos)
CLEAR_BUFFER_AND_RETURN(false);
uPos += 2;
TIWAField oMessageField;
if (!ReadIWAField(pBuffer, uStartPos + unHeaderLen, uPos, oMessageField) || 2 != oMessageField.m_unWireType ||
2 != oMessageField.m_uIndex)
CLEAR_BUFFER_AND_RETURN(false);
size_t uSubPos = oMessageField.m_unStart;
TIWAField oField;
if (!ReadIWAField(pBuffer, oMessageField.m_unEnd, uSubPos, oField) || 0 != oField.m_unWireType ||
1 != oField.m_uIndex)
CLEAR_BUFFER_AND_RETURN(false);
switch (oField.m_oValue)
{
case 1:
{
uint32_t unDataLen = 0;
TIWAField oTempField;
if (ReadIWAField(pBuffer, oMessageField.m_unEnd, uSubPos, oTempField) &&
ReadIWAField(pBuffer, oMessageField.m_unEnd, uSubPos, oTempField) && 0 == oTempField.m_unWireType &&
3 == oTempField.m_uIndex)
unDataLen += oTempField.m_oValue;
size_t unTempPos = uStartPos + unHeaderLen;
// keynote: presentation ref in 2
// number: sheet ref in 1
if (ReadIWAField(pBuffer, uStartPos + unDataLen, unTempPos, oTempField) &&
(2 != oTempField.m_unWireType || 1 != oTempField.m_uIndex || oTempField.m_unEnd - oTempField.m_unStart < 2))
{
nType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY;
CLEAR_BUFFER_AND_RETURN(true);
}
else if (ReadIWAField(pBuffer, uStartPos + unDataLen, unTempPos, oTempField) &&
(2 != oTempField.m_unWireType || 2 != oTempField.m_uIndex || oTempField.m_unEnd - oTempField.m_unStart < 2))
{
nType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS;
CLEAR_BUFFER_AND_RETURN(true);
}
break;
}
case 10000:
{
nType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES;
CLEAR_BUFFER_AND_RETURN(true);
}
}
CLEAR_BUFFER_AND_RETURN(false);
}
bool COfficeFileFormatChecker::isMacFormatFile(const std::wstring& fileName)
{
if (DetectIWorkFormat(fileName, nFileType))
return true;
std::wstring::size_type nExtPos = fileName.rfind(L'.');
std::wstring sExt = L"unknown";
if (nExtPos != std::wstring::npos)
sExt = fileName.substr(nExtPos);
std::transform(sExt.begin(), sExt.end(), sExt.begin(), tolower);
if (0 == sExt.compare(L".pages"))
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES;
else if (0 == sExt.compare(L".numbers"))
nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS;
else if (0 == sExt.compare(L".key"))
nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY;
else
return false;
return true;
delete[] pBuffer;
pBuffer = NULL;
hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Slide.iwa", &pBuffer, nBufferSize);
if (hresult == S_OK && pBuffer != NULL)
{
delete[] pBuffer;
pBuffer = NULL;
nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY;
return true;
}
hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Tables/DataList.iwa", &pBuffer, nBufferSize);
if (hresult == S_OK && pBuffer != NULL)
{
delete[] pBuffer;
pBuffer = NULL;
nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS;
return true;
}
std::wstring::size_type nExtPos = fileName.rfind(L'.');
std::wstring sExt = L"unknown";
if (nExtPos != std::wstring::npos)
sExt = fileName.substr(nExtPos);
std::transform(sExt.begin(), sExt.end(), sExt.begin(), tolower);
if (0 == sExt.compare(L".pages"))
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES;
else if (0 == sExt.compare(L".numbers"))
nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS;
else if (0 == sExt.compare(L".key"))
nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY;
return true;
}
return false;
}
bool COfficeFileFormatChecker::isOpenOfficeFormatFile(const std::wstring &fileName, std::wstring &documentID)
{
documentID.clear();
@ -1679,8 +1496,6 @@ std::wstring COfficeFileFormatChecker::GetExtensionByType(int type)
return L".fodp";
case AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP:
return L".otp";
case AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG:
return L".odg";
case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX:
return L".xlsx";
@ -1753,15 +1568,12 @@ std::wstring COfficeFileFormatChecker::GetExtensionByType(int type)
case AVS_OFFICESTUDIO_FILE_CANVAS_WORD:
case AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET:
case AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION:
case AVS_OFFICESTUDIO_FILE_CANVAS_DRAW:
return L".bin";
case AVS_OFFICESTUDIO_FILE_OTHER_OLD_DOCUMENT:
case AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY:
return L".doct";
case AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY:
return L".xlst";
case AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY:
return L".vsdt";
case AVS_OFFICESTUDIO_FILE_OTHER_OLD_PRESENTATION:
case AVS_OFFICESTUDIO_FILE_OTHER_OLD_DRAWING:
case AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY:
@ -1850,8 +1662,6 @@ int COfficeFileFormatChecker::GetFormatByExtension(const std::wstring &sExt)
return AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT;
if (L".otp" == ext)
return AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP;
if (L".odg" == ext)
return AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG;
if (L".xlsx" == ext)
return AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX;
@ -1925,8 +1735,6 @@ int COfficeFileFormatChecker::GetFormatByExtension(const std::wstring &sExt)
return AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY;
if (L".pptt" == ext)
return AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY;
if (L".vsdt" == ext)
return AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY;
if (L".vsdx" == ext)
return AVS_OFFICESTUDIO_FILE_DRAW_VSDX;

View File

@ -138,14 +138,12 @@
#define AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0001
#define AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0002
#define AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0003
#define AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0004
#define AVS_OFFICESTUDIO_FILE_CANVAS 0x2000
#define AVS_OFFICESTUDIO_FILE_CANVAS_WORD AVS_OFFICESTUDIO_FILE_CANVAS + 0x0001
#define AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET AVS_OFFICESTUDIO_FILE_CANVAS + 0x0002
#define AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION AVS_OFFICESTUDIO_FILE_CANVAS + 0x0003
#define AVS_OFFICESTUDIO_FILE_CANVAS_PDF AVS_OFFICESTUDIO_FILE_CANVAS + 0x0004
#define AVS_OFFICESTUDIO_FILE_CANVAS_DRAW AVS_OFFICESTUDIO_FILE_CANVAS + 0x0005
#define AVS_OFFICESTUDIO_FILE_DRAW 0x4000
#define AVS_OFFICESTUDIO_FILE_DRAW_VSDX AVS_OFFICESTUDIO_FILE_DRAW + 0x0001
@ -153,4 +151,4 @@
#define AVS_OFFICESTUDIO_FILE_DRAW_VSTX AVS_OFFICESTUDIO_FILE_DRAW + 0x0003
#define AVS_OFFICESTUDIO_FILE_DRAW_VSDM AVS_OFFICESTUDIO_FILE_DRAW + 0x0004
#define AVS_OFFICESTUDIO_FILE_DRAW_VSSM AVS_OFFICESTUDIO_FILE_DRAW + 0x0005
#define AVS_OFFICESTUDIO_FILE_DRAW_VSTM AVS_OFFICESTUDIO_FILE_DRAW + 0x0006
#define AVS_OFFICESTUDIO_FILE_DRAW_VSTM AVS_OFFICESTUDIO_FILE_DRAW + 0x0006

View File

@ -109,31 +109,6 @@ win32:!contains(QMAKE_TARGET.arch, x86_64): {
CONFIG += core_win_32
}
linux-clang-libc++ {
CONFIG += core_linux
CONFIG += core_linux_64
CONFIG += core_linux_clang
message("linux-64-clang-libc++")
}
linux-clang-libc++-32 {
CONFIG += core_linux
CONFIG += core_linux_32
CONFIG += core_linux_clang
message("linux-32-clang-libc++")
}
linux-clang {
CONFIG += core_linux
CONFIG += core_linux_64
CONFIG += core_linux_clang
message("linux-64-clang")
}
linux-clang-32 {
CONFIG += core_linux
CONFIG += core_linux_32
CONFIG += core_linux_clang
message("linux-32-clang")
}
linux-g++ {
CONFIG += core_linux
linux-g++:contains(QMAKE_HOST.arch, x86_64): {
@ -221,10 +196,6 @@ core_mac {
}
}
core_linux_clang {
QMAKE_CFLAGS += -Wno-implicit-function-declaration
}
# PREFIXES
core_windows {
CONFIG -= debug_and_release debug_and_release_target
@ -445,12 +416,6 @@ message($$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX)
# COMPILER
CONFIG += c++11
#CONFIG += enable_cpp_17
enable_cpp_17 {
CONFIG += c++1z
DEFINES += _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION
}
!core_windows {
QMAKE_CXXFLAGS += -Wno-register
QMAKE_CFLAGS += -Wno-register
@ -458,11 +423,7 @@ enable_cpp_17 {
core_linux {
core_static_link_libstd {
!core_linux_clang {
QMAKE_LFLAGS += -static-libstdc++ -static-libgcc
} else {
# TODO: add libc++abi?
}
QMAKE_LFLAGS += -static-libstdc++ -static-libgcc
message(core_static_link_libstd)
}
plugin {

View File

@ -207,9 +207,9 @@ namespace agg
}
p[Order::A] = (value_type)((alpha + a) - ((alpha * a + base_mask) >> base_shift));
if (r != cr) p[Order::R] = (value_type)((alpha * cr + a * r - ((a * r * alpha + base_mask) >> base_shift)) / p[Order::A]);
if (g != cg) p[Order::G] = (value_type)((alpha * cg + a * g - ((a * g * alpha + base_mask) >> base_shift)) / p[Order::A]);
if (b != cb) p[Order::B] = (value_type)((alpha * cb + a * b - ((a * b * alpha + base_mask) >> base_shift)) / p[Order::A]);
p[Order::R] = (value_type)((alpha * cr + a * r - ((a * r * alpha + base_mask) >> base_shift)) / p[Order::A]);
p[Order::G] = (value_type)((alpha * cg + a * g - ((a * g * alpha + base_mask) >> base_shift)) / p[Order::A]);
p[Order::B] = (value_type)((alpha * cb + a * b - ((a * b * alpha + base_mask) >> base_shift)) / p[Order::A]);
}
static AGG_INLINE void blend_pix_subpix(value_type* p,

View File

@ -332,7 +332,6 @@
* DBL_MAX Maximum floating point number (can be set to an arbitrary value)
*/
# include <float.h>
# include <math.h>
# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)

View File

@ -33,7 +33,6 @@
#define DOC_BUILDER_ADDON_PRIVATE
#include <string>
#include "../docbuilder.h"
namespace NSDoctRenderer
{
@ -47,11 +46,11 @@ namespace NSDoctRenderer
m_sWorkDirectory = sWorkDir;
}
public:
std::wstring GetX2tSaveAddon(NSDoctRenderer::CDocBuilder* builder, const int& filetype)
std::wstring GetX2tSaveAddon()
{
return L"";
}
int GetX2tPreSaveError(NSDoctRenderer::CDocBuilder* builder, const int& filetype)
int GetX2tPreSaveError()
{
return 0;
}

View File

@ -33,7 +33,6 @@
#include "./../common_deploy.h"
#include "../docbuilder.h"
#include "../../common/File.h"
#include "../../common/SystemUtils.h"
#ifdef LINUX
#include "../../../DesktopEditor/common/File.h"
@ -79,13 +78,6 @@ void parse_args(NSDoctRenderer::CDocBuilder* builder, int argc, char *argv[])
}
}
bool CheckLicense(const std::wstring& sSrc, const std::wstring& sDst)
{
NSFile::CFileBinary::Remove(sDst);
NSFile::CFileBinary::Copy(sSrc, sDst);
return NSFile::CFileBinary::Exists(sDst);
}
#ifdef WIN32
int wmain(int argc, wchar_t *argv[])
#else
@ -97,7 +89,6 @@ int main(int argc, char *argv[])
bool bIsHelp = false;
bool bIsFonts = false;
bool bIsLicense = false;
for (int i = 0; i < argc; ++i)
{
#ifdef WIN32
@ -130,33 +121,6 @@ int main(int argc, char *argv[])
{
bIsFonts = true;
}
else if (sParam == "-register")
{
bIsLicense = true;
}
else
{
if (bIsLicense)
{
std::wstring sLicensePathSrc = UTF8_TO_U(sParam);
if (!NSFile::CFileBinary::Exists(sLicensePathSrc))
return 1;
std::wstring sLicensePath = NSSystemUtils::GetEnvVariable(L"ONLYOFFICE_BUILDER_LICENSE");
if (CheckLicense(sLicensePathSrc, sLicensePath))
return 0;
sLicensePath = NSFile::GetProcessDirectory() + L"/license.xml";
if (CheckLicense(sLicensePathSrc, sLicensePath))
return 0;
sLicensePath = NSSystemUtils::GetAppDataDir() + L"/docbuilder/license.xml";
if (CheckLicense(sLicensePathSrc, sLicensePath))
return 0;
return 1;
}
}
}
if (bIsFonts)

View File

@ -475,13 +475,6 @@ namespace NSDoctRenderer
*/
void SetPropertyW(const wchar_t* param, const wchar_t* value);
/**
* GetProperty method.
* @param param The parameter name in the Unicode format, the value is always --argument.
* @return int value for property
*/
int GetPropertyInt(const wchar_t* param);
/**
* Writes data to the log file. It is used for logs in JS code.
* @param path The path to the file where all the logs will be written.

View File

@ -2,7 +2,6 @@ import ctypes
import os
import platform
import atexit
import subprocess
OBJECT_HANDLE = ctypes.c_void_p
STRING_HANDLE = ctypes.c_void_p
@ -609,15 +608,8 @@ class FileTypes:
PNG = _IMAGE_MASK + 0x0005
BMP = _IMAGE_MASK + 0x0008
# NOTE: do not change builder_path manually!
builder_path = os.path.dirname(os.path.realpath(__file__))
_loadLibrary(builder_path)
CDocBuilder.Initialize(builder_path)
def registerLibrary(license_path):
docbuilder_bin = os.path.join(builder_path, "docbuilder")
if ("windows" == platform.system().lower()):
docbuilder_bin += ".exe"
return subprocess.call([docbuilder_bin, "-register", license_path], stderr=subprocess.STDOUT, shell=True)
atexit.register(CDocBuilder.Dispose)

View File

@ -1596,15 +1596,6 @@ namespace NSDoctRenderer
return this->SetProperty(sA.c_str(), value);
}
int CDocBuilder::GetPropertyInt(const wchar_t* param)
{
std::wstring sParam = std::wstring(param);
std::string sParamA = U_TO_UTF8(sParam);
if ("--save-use-only-names" == sParamA)
return m_pInternal->m_bIsServerSafeVersion ? 1 : 0;
return -1;
}
void CDocBuilder::Initialize(const wchar_t* directory)
{
std::wstring sDirectory = L"";

View File

@ -1003,7 +1003,7 @@ namespace NSDoctRenderer
CDocBuilderAddon oSaveAddon(m_sX2tPath);
int nPreSaveError = oSaveAddon.GetX2tPreSaveError(m_pParent, m_nFileType);
int nPreSaveError = oSaveAddon.GetX2tPreSaveError();
if (0 != nPreSaveError)
return nPreSaveError;
@ -1090,7 +1090,7 @@ namespace NSDoctRenderer
if (!sOptions.empty())
oBuilder.WriteString(UTF8_TO_U(sOptions));
oBuilder.WriteString(oSaveAddon.GetX2tSaveAddon(m_pParent, m_nFileType));
oBuilder.WriteString(oSaveAddon.GetX2tSaveAddon());
oBuilder.WriteString(L"</TaskQueueDataConvert>");

View File

@ -165,14 +165,9 @@ JSSmart<CJSValue> CGraphicsEmbed::create(JSSmart<CJSValue> Native, JSSmart<CJSVa
JSSmart<CJSObject> pNativeObject = Native->toObject();
CJSEmbedObject* pNativeEmbedObject = pNativeObject->getNative();
if (m_pInternal->m_pAppImage && pNativeEmbedObject)
{
if (m_pInternal->m_pAppImage)
delete m_pInternal->m_pAppImage;
m_pInternal->m_pAppImage = NULL;
}
if (NULL == m_pInternal->m_pAppImage)
m_pInternal->m_pAppImage = new CGraphicsAppImage();
m_pInternal->m_pAppImage = new CGraphicsAppImage();
if (pNativeEmbedObject)
{

View File

@ -351,11 +351,17 @@ CFontManager::~CFontManager()
RELEASEINTERFACE(m_pFont);
RELEASEOBJECT(m_pOwnerCache);
}
void CFontManager::SetOwnerCache(NSFonts::IFontsCache* pCache)
{
m_pOwnerCache = (CFontsCache*)pCache;
}
void CFontManager::ClearOwnerCache()
{
m_pOwnerCache->Clear();
}
NSFonts::IFontsCache* CFontManager::GetCache() { return m_pOwnerCache; }
NSFonts::IApplicationFonts* CFontManager::GetApplication() { return m_pApplication; }
NSFonts::IFontFile* CFontManager::GetFile() { return m_pFont; }

View File

@ -132,6 +132,7 @@ public:
virtual void Initialize();
virtual void SetOwnerCache(NSFonts::IFontsCache* pCache);
virtual void ClearOwnerCache();
virtual NSFonts::IFontsCache* GetCache();
virtual NSFonts::IApplicationFonts* GetApplication();

View File

@ -451,7 +451,7 @@ namespace NSShaper
CheckUnicodeFaceName(face, family_name, family_name_len);
unsigned int nLen1 = (unsigned int)family_name_len;
unsigned int nLen2 = (unsigned int)((face->style_name != NULL) ? strlen(face->style_name) : 0);
unsigned int nLen2 = (unsigned int)strlen(face->style_name);
unsigned int nLen = 28 + nLen1 + 1 + nLen2 + 1 + 1 + (int)face->num_fixed_sizes;
@ -693,13 +693,6 @@ namespace NSShaper
g_userfeatures_init = true;
}
// Turn on ligatures on arabic script
if (nScript == HB_SCRIPT_ARABIC ||
nScript == HB_SCRIPT_SYRIAC)
{
nFeatures |= 1;
}
// font
hb_font_t* pFont;
if (NULL == font)

View File

@ -94,14 +94,11 @@ void CheckUnicodeFaceName(FT_Face pFace, int*& UName, unsigned int& ULen)
bool isBadASCII = false;
unsigned int face_name_len = 0;
if (NULL != face_name)
while ('\0' != face_name[face_name_len])
{
while ('\0' != face_name[face_name_len])
{
if ('?' == face_name[face_name_len])
isBadASCII = true;
++face_name_len;
}
if ('?' == face_name[face_name_len])
isBadASCII = true;
++face_name_len;
}
if (face_name_len > 6 &&

View File

@ -594,13 +594,6 @@ WASM_EXPORT unsigned char* ASC_HB_ShapeText(FT_Face pFace, hb_font_t* pFont, cha
g_userfeatures_init = true;
}
// Turn on ligatures on arabic script
if (nScript == HB_SCRIPT_ARABIC ||
nScript == HB_SCRIPT_SYRIAC)
{
nFeatures |= 1;
}
// font
if (NULL == pFont)
{

View File

@ -33,479 +33,647 @@
namespace Aggplus
{
////////////////////////////////////////////////////////////////////////////////
CBrush::CBrush(BrushType bType) : m_bType(bType)
CBrush::CBrush()
{
}
CBrush::CBrush(const BrushType& type)
: m_bType(type)
{
}
CBrush::~CBrush()
{
}
BrushType CBrush::GetType() const
{
return m_bType;
BrushType CBrush::GetType() const
{
return m_bType;
}
////////////////////////////////////////////////////////////////////////////////
CBrushSolid::CBrushSolid(CColor dwColor) : CBrush(BrushTypeSolidColor), m_dwColor(dwColor)
CBrushSolid::CBrushSolid() : CBrush()
{
}
CBrushSolid::~CBrushSolid()
CBrushSolid::CBrushSolid(CColor color)
: CBrush(),
m_dwColor(color)
{
}
CBrush* CBrushSolid::Clone() const
{
return new CBrushSolid(m_dwColor);
CBrushSolid::CBrushSolid(const CBrushSolid& other) : CBrush()
{
*this = other;
}
void CBrushSolid::GetColor(CColor* color) const { *color = m_dwColor; }
void CBrushSolid::SetColor(const CColor &color) { m_dwColor = color; }
////////////////////////////////////////////////////////////////////////////////
CBrushHatch::CBrushHatch() : CBrush(BrushTypeHatchFill)
CBrushSolid::~CBrushSolid()
{
}
CBrushHatch::~CBrushHatch()
void CBrushSolid::GetColor(CColor* color) const
{
*color = m_dwColor;
}
void CBrushSolid::SetColor(const CColor &color)
{
m_dwColor = color;
}
CBrushSolid& CBrushSolid::operator=(const CBrushSolid& other)
{
if (this == &other)
return *this;
m_dwColor = other.m_dwColor;
return *this;
}
CBrushHatch::CBrushHatch()
: CBrush(BrushTypeHatchFill)
{
}
CBrush* CBrushHatch::Clone() const
{
CBrushHatch* clone = new CBrushHatch();
clone->m_name = m_name;
clone->m_dwColor1 = m_dwColor1;
clone->m_dwColor2 = m_dwColor2;
return clone;
}
////////////////////////////////////////////////////////////////////////////////
CBrushLinearGradient::CBrushLinearGradient( const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2 )
CBrushHatch::CBrushHatch(const CBrushHatch& other)
: CBrush(BrushTypeHatchFill)
{
*this = other;
}
CBrushHatch::CBrushHatch(CBrushHatch&& other) noexcept
: CBrush(BrushTypeHatchFill)
{
*this = std::move(other);
}
CBrushHatch::~CBrushHatch()
{
}
void CBrushHatch::SetName(const std::wstring& name)
{
m_wsName = name;
}
std::wstring CBrushHatch::GetName() const
{
return m_wsName;
}
void CBrushHatch::SetColor1(const CColor& color)
{
m_dwColor1 = color;
}
CColor CBrushHatch::GetColor1() const
{
return m_dwColor1;
}
void CBrushHatch::SetColor2(const CColor& color)
{
m_dwColor2 = color;
}
CColor CBrushHatch::GetColor2() const
{
return m_dwColor2;
}
void CBrushHatch::SetBounds(const CDoubleRect& rect)
{
m_oBounds = rect;
}
CDoubleRect& CBrushHatch::GetBounds()
{
return m_oBounds;
}
CBrushHatch& CBrushHatch::operator=(const CBrushHatch& other)
{
if (this == &other)
return *this;
m_wsName = other.m_wsName;
m_dwColor1 = other.m_dwColor1;
m_dwColor2 = other.m_dwColor2;
return *this;
}
CBrushHatch& CBrushHatch::operator=(CBrushHatch&& other) noexcept
{
if (this == &other)
return *this;
m_wsName = std::move(other.m_wsName);
m_dwColor1 = other.m_dwColor1;
m_dwColor2 = other.m_dwColor2;
return *this;
}
CBrushLinearGradient::CBrushLinearGradient()
: CBrush(BrushTypeLinearGradient)
{
m_points[0] = p1;
m_points[1] = p2;
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = 0;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = FALSE;
m_bRectable = FALSE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient::CBrushLinearGradient( const Point& p1, const Point& p2, const CColor& c1, const CColor& c2 )
CBrushLinearGradient::CBrushLinearGradient(const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2)
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (float)p1.X;
m_points[0].Y = (float)p1.Y;
m_points[1].X = (float)p2.X;
m_points[1].Y = (float)p2.Y;
m_arPoints[0] = p1;
m_arPoints[1] = p2;
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = 0;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = FALSE;
m_bRectable = FALSE;
m_bRelativeCoords = FALSE;
m_arColors[0] = c1;
m_arColors[1] = c2;
}
CBrushLinearGradient::CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable )
CBrushLinearGradient::CBrushLinearGradient(const Point& p1, const Point& p2, const CColor& c1, const CColor& c2)
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = rect.GetLeft();
m_points[0].Y = rect.GetTop();
m_points[1].X = rect.GetRight();
m_points[1].Y = rect.GetBottom();
m_arPoints[0].X = static_cast<float>(p1.X);
m_arPoints[0].Y = static_cast<float>(p1.Y);
m_arPoints[1].X = static_cast<float>(p2.X);
m_arPoints[1].Y = static_cast<float>(p2.Y);
m_colors[0] = c1;
m_colors[1] = c2;
m_arColors[0] = c1;
m_arColors[1] = c2;
}
m_angle = angle;
m_wrap = Aggplus::WrapModeTile;
CBrushLinearGradient::CBrushLinearGradient(const RectF& rect, const CColor& c1, const CColor& c2, float angle, bool isAngleScalable)
: CBrush(BrushTypeLinearGradient)
{
m_arPoints[0].X = rect.GetLeft();
m_arPoints[0].Y = rect.GetTop();
m_arPoints[1].X = rect.GetRight();
m_arPoints[1].Y = rect.GetBottom();
m_arColors[0] = c1;
m_arColors[1] = c2;
m_fAngle = angle;
m_bAngleScalable = isAngleScalable;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
m_bRectable = true;
}
CBrushLinearGradient::CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable )
CBrushLinearGradient::CBrushLinearGradient(const Rect& rect, const CColor& c1, const CColor& c2, float angle, bool isAngleScalable)
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (float)rect.GetLeft();
m_points[0].Y = (float)rect.GetTop();
m_points[1].X = (float)rect.GetRight();
m_points[1].Y = (float)rect.GetBottom();
m_arPoints[0].X = static_cast<float>(rect.GetLeft());
m_arPoints[0].Y = static_cast<float>(rect.GetTop());
m_arPoints[1].X = static_cast<float>(rect.GetRight());
m_arPoints[1].Y = static_cast<float>(rect.GetBottom());
m_colors[0] = c1;
m_colors[1] = c2;
m_arColors[0] = c1;
m_arColors[1] = c2;
m_angle = angle;
m_wrap = Aggplus::WrapModeTile;
m_fAngle = angle;
m_bAngleScalable = isAngleScalable;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
m_bRectable = true;
}
CBrushLinearGradient::CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode )
CBrushLinearGradient::CBrushLinearGradient(const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode)
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = rect.GetLeft();
m_points[0].Y = rect.GetTop();
m_points[1].X = rect.GetRight();
m_points[1].Y = rect.GetBottom();
m_arPoints[0].X = rect.GetLeft();
m_arPoints[0].Y = rect.GetTop();
m_arPoints[1].X = rect.GetRight();
m_arPoints[1].Y = rect.GetBottom();
switch( mode )
{
case LinearGradientModeHorizontal:
m_angle = 0;
m_fAngle = 0;
break;
case LinearGradientModeVertical:
m_angle = 90;
m_fAngle = 90;
break;
case LinearGradientModeForwardDiagonal:
m_angle = 45;
m_fAngle = 45;
break;
default:
m_angle = 315;
m_fAngle = 315;
}
m_colors[0] = c1;
m_colors[1] = c2;
m_arColors[0] = c1;
m_arColors[1] = c2;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = TRUE;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
m_bAngleScalable = true;
m_bRectable = true;
}
CBrushLinearGradient::CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode )
CBrushLinearGradient::CBrushLinearGradient(const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode)
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (REAL)rect.GetLeft();
m_points[0].Y = (REAL)rect.GetTop();
m_points[1].X = (REAL)rect.GetRight();
m_points[1].Y = (REAL)rect.GetBottom();
m_arPoints[0].X = static_cast<float>(rect.GetLeft());
m_arPoints[0].Y = static_cast<float>(rect.GetTop());
m_arPoints[1].X = static_cast<float>(rect.GetRight());
m_arPoints[1].Y = static_cast<float>(rect.GetBottom());
switch( mode )
{
case LinearGradientModeHorizontal:
m_angle = 0;
m_fAngle = 0;
break;
case LinearGradientModeVertical:
m_angle = 90;
m_fAngle = 90;
break;
case LinearGradientModeForwardDiagonal:
m_angle = 45;
m_fAngle = 45;
break;
default:
m_angle = 315;
m_fAngle = 315;
}
m_colors[0] = c1;
m_colors[1] = c2;
m_arColors[0] = c1;
m_arColors[1] = c2;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = TRUE;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
m_bAngleScalable = true;
m_bRectable = true;
}
CBrushLinearGradient::CBrushLinearGradient( const CBrushLinearGradient& out )
: CBrush(out.m_bType)
CBrushLinearGradient::CBrushLinearGradient(const CBrushLinearGradient& other)
: CBrush(other.m_bType)
{
m_colors[0] = out.m_colors[0];
m_colors[1] = out.m_colors[1];
m_points[0] = out.m_points[0];
m_points[1] = out.m_points[1];
m_subcolors = out.m_subcolors;
m_matrix = out.m_matrix;
m_angle = out.m_angle;
m_wrap = out.m_wrap;
m_bAngleScalable = out.m_bAngleScalable;
m_bRectable = out.m_bRectable;
m_bRelativeCoords = out.m_bRelativeCoords;
*this = other;
}
Status CBrushLinearGradient::GetLinearColors( CColor* colors ) const
CBrushLinearGradient::CBrushLinearGradient(CBrushLinearGradient&& other) noexcept
{
if( !colors )
*this = std::move(other);
}
CBrushLinearGradient::~CBrushLinearGradient()
{
}
Status CBrushLinearGradient::GetLinearColors(CColor* colors) const
{
if(!colors)
return InvalidParameter;
colors[0] = m_colors[0];
colors[1] = m_colors[1];
colors[0] = m_arColors[0];
colors[1] = m_arColors[1];
return Ok;
}
Status CBrushLinearGradient::GetRectangle( Rect *rect ) const
Status CBrushLinearGradient::GetRectangle(Rect *rect) const
{
if( !rect )
if(!rect)
return InvalidParameter;
rect->X = (int)( m_points[0].X );
rect->Y = (int)( m_points[0].Y );
rect->Width = (int)( m_points[1].X ) - rect->X;
rect->Height = (int)( m_points[1].Y ) - rect->Y;
rect->X = static_cast<int>((m_arPoints[0].X));
rect->Y = static_cast<int>((m_arPoints[0].Y));
rect->Width = static_cast<int>((m_arPoints[1].X) - rect->X);
rect->Height = static_cast<int>((m_arPoints[1].Y) - rect->Y);
return Ok;
}
Status CBrushLinearGradient::GetRectangle(RectF *rect) const
{
if(!rect)
return InvalidParameter;
rect->X = m_arPoints[0].X;
rect->Y = m_arPoints[0].Y;
rect->Width = m_arPoints[1].X - rect->X;
rect->Height = m_arPoints[1].Y - rect->Y;
return Ok;
}
Status CBrushLinearGradient::GetRectangle( RectF *rect ) const
Status CBrushLinearGradient::GetTransform(CMatrix* matrix) const
{
if( !rect )
if(!matrix)
return InvalidParameter;
rect->X = m_points[0].X;
rect->Y = m_points[0].Y;
rect->Width = m_points[1].X - rect->X;
rect->Height = m_points[1].Y - rect->Y;
*matrix = m_Matrix;
return Ok;
}
Status CBrushLinearGradient::GetTransform( CMatrix* matrix ) const
Status CBrushLinearGradient::MultiplyTransform(const CMatrix *matrix, MatrixOrder order)
{
if( !matrix )
return InvalidParameter;
*matrix = m_matrix;
return Ok;
}
Status CBrushLinearGradient::MultiplyTransform( const CMatrix *matrix, MatrixOrder order)
{
if( !matrix )
return InvalidParameter;
m_matrix.Multiply( matrix, order );
m_Matrix.Multiply(matrix, order);
return Ok;
}
Status CBrushLinearGradient::ResetTransform()
{
m_matrix.Reset();
m_Matrix.Reset();
return Ok;
}
Status CBrushLinearGradient::RotateTransform( REAL angle, MatrixOrder order )
Status CBrushLinearGradient::RotateTransform(float angle, MatrixOrder order)
{
m_matrix.Rotate( angle, order );
m_Matrix.Rotate(angle, order);
return Ok;
}
Status CBrushLinearGradient::ScaleTransform( REAL sx, REAL sy, MatrixOrder order )
Status CBrushLinearGradient::ScaleTransform(float sx, float sy, MatrixOrder order)
{
m_matrix.Scale( sx, sy, order );
m_Matrix.Scale(sx, sy, order);
return Ok;
}
void CBrushLinearGradient::SetWrapMode( WrapMode mode )
void CBrushLinearGradient::SetWrapMode(WrapMode mode)
{
m_wrap = mode;
m_eWrap = mode;
}
WrapMode CBrushLinearGradient::GetWrapMode() const
{
return m_wrap;
return m_eWrap;
}
CBrush* CBrushLinearGradient::Clone() const
Status CBrushLinearGradient::SetInterpolationColors(const CColor *presetColors, const float *blendPositions, int count)
{
return new CBrushLinearGradient( *this );
}
m_arSubColors.clear();
Status CBrushLinearGradient::SetInterpolationColors( const CColor *presetColors, const REAL *blendPositions, INT count )
{
m_subcolors.clear();
if( count > 0 && presetColors && blendPositions )
if(count > 0 && presetColors && blendPositions)
{
m_subcolors.resize( count );
m_arSubColors.resize(count);
for( int i = 0; i < count; i++ )
for(int i = 0; i < count; i++)
{
m_subcolors[i].color = presetColors[i];
m_subcolors[i].position = blendPositions[i];
m_arSubColors[i].color = presetColors[i];
m_arSubColors[i].position = blendPositions[i];
}
}
return Ok;
}
Status CBrushLinearGradient::GetInterpolationColors( CColor *presetColors, REAL *blendPositions, INT count ) const
Status CBrushLinearGradient::GetInterpolationColors(CColor *presetColors, float *blendPositions, int count) const
{
if( count > 0 && count <= (INT)m_subcolors.size() && presetColors && blendPositions )
if( count > 0 && count <= (int)m_arSubColors.size() && presetColors && blendPositions )
{
for( int i = 0; i < count; i++ )
{
presetColors[i] = m_subcolors[i].color;
blendPositions[i] = m_subcolors[i].position;
presetColors[i] = m_arSubColors[i].color;
blendPositions[i] = m_arSubColors[i].position;
}
}
return Ok;
}
INT CBrushLinearGradient::GetInterpolationColorsCount() const
int CBrushLinearGradient::GetInterpolationColorsCount() const
{
return (INT)m_subcolors.size();
return static_cast<int>(m_arSubColors.size());
}
// additional methods
void CBrushLinearGradient::GetSubColor( int nIndex, CColor* pColor, float* pPosition ) const
void CBrushLinearGradient::GetSubColor(int index, CColor* color, float* position) const
{
*pColor = m_subcolors[nIndex].color;
*pPosition = m_subcolors[nIndex].position;
*color = m_arSubColors[index].color;
*position = m_arSubColors[index].position;
}
void CBrushLinearGradient::SetRelativeCoords( INT bRelative )
void CBrushLinearGradient::SetRelativeCoords(bool relative)
{
m_bRelativeCoords = bRelative;
m_bRelativeCoords = relative;
}
INT CBrushLinearGradient::IsRelativeCoords() const
bool CBrushLinearGradient::IsRelativeCoords() const
{
return m_bRelativeCoords;
}
INT CBrushLinearGradient::IsAngleScalable() const
bool CBrushLinearGradient::IsAngleScalable() const
{
return m_bAngleScalable;
}
INT CBrushLinearGradient::IsRectable() const
bool CBrushLinearGradient::IsRectable() const
{
return m_bRectable;
}
float CBrushLinearGradient::GetAngle() const
{
return m_angle;
return m_fAngle;
}
////////////////////////////////////////////////////////////////////////////////
CBrushTexture::CBrushTexture() : CBrush(BrushTypeTextureFill)
void CBrushLinearGradient::SetBounds(const CDoubleRect& rect)
{
m_pImage = NULL;
m_bReleaseImage = FALSE;
Alpha = 255;
m_bUseBounds = false;
m_oBounds = rect;
}
CBrushTexture::CBrushTexture(const std::wstring& strName, WrapMode wrapMode) : CBrush(BrushTypeTextureFill), m_wrapMode(wrapMode)
CDoubleRect& CBrushLinearGradient::GetBounds()
{
m_pImage = new CImage(strName);
m_bReleaseImage = TRUE;
Alpha = 255;
m_bUseBounds = false;
return m_oBounds;
}
CBrushTexture::CBrushTexture(CImage *pImage, WrapMode wrapMode) : CBrush(BrushTypeTextureFill), m_wrapMode(wrapMode)
CBrushLinearGradient& CBrushLinearGradient::operator=(const CBrushLinearGradient& other)
{
m_pImage = pImage;
m_bReleaseImage = FALSE;
Alpha = 255;
m_bUseBounds = false;
if (this == &other)
return *this;
m_arColors[0] = other.m_arColors[0];
m_arColors[1] = other.m_arColors[1];
m_arPoints[0] = other.m_arPoints[0];
m_arPoints[1] = other.m_arPoints[1];
m_arSubColors = other.m_arSubColors;
m_Matrix = other.m_Matrix;
m_fAngle = other.m_fAngle;
m_eWrap = other.m_eWrap;
m_bAngleScalable = other.m_bAngleScalable;
m_bRectable = other.m_bRectable;
m_bRelativeCoords = other.m_bRelativeCoords;
return *this;
}
CBrushTexture::~CBrushTexture()
CBrushLinearGradient& CBrushLinearGradient::operator=(CBrushLinearGradient&& other) noexcept
{
if (this == &other)
return *this;
m_arColors[0] = other.m_arColors[0];
m_arColors[1] = other.m_arColors[1];
m_arPoints[0] = other.m_arPoints[0];
m_arPoints[1] = other.m_arPoints[1];
m_arSubColors = other.m_arSubColors;
m_Matrix = std::move(other.m_Matrix);
m_eWrap = other.m_eWrap;
m_bAngleScalable = other.m_bAngleScalable;
m_bRectable = other.m_bRectable;
m_bRelativeCoords = other.m_bRelativeCoords;
return *this;
}
CBrushTexture::CBrushTexture()
: CBrush(BrushTypeTextureFill)
{
}
CBrushTexture::CBrushTexture(const std::wstring& name, WrapMode mode)
: CBrush(BrushTypeTextureFill),
m_eWrapMode(mode)
{
m_pImage = new CImage(name);
m_bReleaseImage = true;
}
CBrushTexture::CBrushTexture(CImage *image, WrapMode mode)
: CBrush(BrushTypeTextureFill),
m_eWrapMode(mode)
{
m_pImage = image;
}
CBrushTexture::CBrushTexture(const CBrushTexture& other)
{
*this = other;
}
CBrushTexture::CBrushTexture(CBrushTexture&& other)
{
*this = std::move(other);
}
CBrushTexture::~CBrushTexture()
{
if (m_bReleaseImage)
{
RELEASEOBJECT(m_pImage);
}
}
CBrush* CBrushTexture::Clone() const
void CBrushTexture::TranslateTransform(double x, double y, MatrixOrder order)
{
CBrushTexture *pRet = new CBrushTexture(m_pImage, m_wrapMode);
if( pRet )
{
pRet->m_mtx = m_mtx;
}
return pRet;
m_Matrix.Translate(x, y, order);
}
void CBrushTexture::TranslateTransform(double dX, double dY, MatrixOrder order)
{
m_mtx.Translate(dX, dY, order);
}
void CBrushTexture::ScaleTransform(double dX, double dY, MatrixOrder order)
{
m_mtx.Scale(dX, dY, order);
}
void CBrushTexture::RotateTransform(double angle, MatrixOrder order)
{
m_mtx.Rotate(angle, order);
}
void CBrushTexture::GetTransform(CMatrix* matrix) const
{
*matrix = m_mtx;
}
void CBrushTexture::SetTransform(const CMatrix* matrix)
{
m_mtx = *matrix;
void CBrushTexture::ScaleTransform(double x, double y, MatrixOrder order)
{
m_Matrix.Scale(x, y, order);
}
void CBrushTexture::SetWrapMode(WrapMode wMode)
{
m_wrapMode = wMode;
void CBrushTexture::RotateTransform(double angle, MatrixOrder order)
{
m_Matrix.Rotate(angle, order);
}
WrapMode CBrushTexture::GetWrapMode() const
{
return(m_wrapMode);
void CBrushTexture::GetTransform(CMatrix* matrix) const
{
*matrix = m_Matrix;
}
void CBrushTexture::SetTransform(const CMatrix* matrix)
{
m_Matrix = *matrix;
}
void CBrushTexture::SetWrapMode(WrapMode mode)
{
m_eWrapMode = mode;
}
WrapMode CBrushTexture::GetWrapMode() const
{
return m_eWrapMode;
}
void CBrushTexture::SetBounds(const CDoubleRect& rect)
{
m_bUseBounds = true;
m_oBounds = rect;
}
CDoubleRect& CBrushTexture::GetBounds()
{
return m_oBounds;
}
void CBrushTexture::SetReleaseImage(bool isReleaseImage)
{
m_bReleaseImage = isReleaseImage;
}
bool CBrushTexture::IsReleaseImage() const
{
return m_bReleaseImage;
}
void CBrushTexture::SetAlpha(BYTE alpha)
{
m_Alpha = alpha;
}
BYTE CBrushTexture::GetAlpha() const
{
return m_Alpha;
}
void* CBrushTexture::GetData()
{
return m_pImage->m_pImgData;
}
void* CBrushTexture::PatternFinalize()
{
{
if (m_pImage->m_nStride < 0)
return m_pImage->m_pImgData - ((m_pImage->m_dwHeight - 1) * m_pImage->m_nStride);
return m_pImage->m_pImgData;
}
DWORD CBrushTexture::PatternGetWidth()
{
{
return m_pImage->m_dwWidth;
}
DWORD CBrushTexture::PatternGetHeight()
{
{
return m_pImage->m_dwHeight;
}
int CBrushTexture::PatternGetStride()
{
{
return m_pImage->m_nStride;
}
CBrushTexture& CBrushTexture::operator=(const CBrushTexture& other)
{
if (this == &other)
return *this;
m_pImage = new CImage(*other.m_pImage);
m_Matrix = other.m_Matrix;
m_eWrapMode = other.m_eWrapMode;
return *this;
}
CBrushTexture& CBrushTexture::operator=(CBrushTexture&& other)
{
if (this == &other)
return *this;
m_pImage = std::move(other.m_pImage);
m_Matrix = std::move(other.m_Matrix);
m_eWrapMode = other.m_eWrapMode;
return *this;
}
}

View File

@ -43,170 +43,256 @@
namespace Aggplus
{
class CBrush
{
friend class CGraphics;
protected:
CBrush(BrushType bType);
public:
virtual ~CBrush();
virtual CBrush* Clone() const = 0;
BrushType GetType() const;
public:
BrushType m_bType;
};
class CBrushSolid : public CBrush
{
public:
CBrushSolid(CColor dwColor);
virtual ~CBrushSolid();
virtual CBrush *Clone() const;
void GetColor(CColor* color) const;
void SetColor(const CColor &color);
protected:
CColor m_dwColor;
};
class CBrushHatch : public CBrush
{
public:
CBrushHatch();
virtual ~CBrushHatch();
virtual CBrush *Clone() const;
inline CDoubleRect& GetBounds() { return Bounds; }
public:
std::wstring m_name;
CColor m_dwColor1;
CColor m_dwColor2;
CDoubleRect Bounds;
};
class CBrushLinearGradient : public CBrush
{
friend class CGraphics;
public:
CBrushLinearGradient( const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2 );
CBrushLinearGradient( const Point& p1, const Point& p2, const CColor& c1, const CColor& c2 );
CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable );
CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable );
CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode );
CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode );
CBrushLinearGradient( const CBrushLinearGradient& out );
Status GetLinearColors( CColor* colors ) const;
Status GetRectangle( Rect *rect ) const;
Status GetRectangle( RectF *rect ) const;
Status GetTransform( CMatrix* matrix ) const;
Status MultiplyTransform( const CMatrix *matrix, MatrixOrder order = MatrixOrderPrepend);
Status ResetTransform();
Status RotateTransform( REAL angle, MatrixOrder order = MatrixOrderPrepend );
Status ScaleTransform( REAL sx, REAL sy, MatrixOrder order = MatrixOrderPrepend );
void SetWrapMode( WrapMode mode );
WrapMode GetWrapMode() const;
virtual CBrush *Clone() const;
Status SetInterpolationColors( const CColor *presetColors, const REAL *blendPositions, INT count );
Status GetInterpolationColors( CColor *presetColors, REAL *blendPositions, INT count ) const;
INT GetInterpolationColorsCount() const;
// additional methods
void GetSubColor( int nIndex, CColor* pColor, float* pPosition ) const;
void SetRelativeCoords( INT bRelative );
INT IsRelativeCoords() const;
INT IsAngleScalable() const;
INT IsRectable() const;
float GetAngle() const;
inline void SetBounds(const CDoubleRect& oRect) { Bounds = oRect; }
inline CDoubleRect& GetBounds() { return Bounds; }
// info about gradient
NSStructures::GradientInfo m_oGradientInfo; // used in 60xx grad types
protected:
CColor m_colors[2];
PointF m_points[2];
struct TSubColor
/**
* @abstract CBrush
*
* Base class for brushes (by default a solid brush
* is created).
*/
class CBrush
{
CColor color;
float position;
friend class CGraphics;
protected:
CBrush();
CBrush(const BrushType& type);
public:
virtual ~CBrush();
BrushType GetType() const;
public:
BrushType m_bType = BrushTypeSolidColor;
};
std::vector<TSubColor> m_subcolors;
CMatrix m_matrix;
float m_angle; // угол поворота в градусах базовой линии p1 -> p2
/**
* @class CBrushSolid
*
* A single-color brush used to draw text, graphic paths,
* and fills with a single color.
*/
class CBrushSolid : public CBrush
{
public:
CBrushSolid();
CBrushSolid(CColor color);
virtual ~CBrushSolid();
CBrushSolid(const CBrushSolid& other);
CDoubleRect Bounds;
void GetColor(CColor* color) const;
void SetColor(const CColor &color);
Aggplus::WrapMode m_wrap;
CBrushSolid& operator=(const CBrushSolid& other);
protected:
CColor m_dwColor{};
};
INT m_bAngleScalable; // масштабировать угол поворота относительно заданных точек b = arctan( width / height * tan(angle) );
INT m_bRectable; // в качестве направляющей используется диагональ прямоугольника
INT m_bRelativeCoords; // координаты точек считаются относительно рисуемого примитива
};
/**
* @class CBrushHatch
*
* A two-color brush used to fill graphic paths using
* one of the hatch patterns
*/
class CBrushHatch : public CBrush
{
public:
CBrushHatch();
CBrushHatch(const CBrushHatch& other);
CBrushHatch(CBrushHatch&& other) noexcept;
virtual ~CBrushHatch();
class CBrushTexture : public CBrush
{
friend class CGraphics;
protected:
CBrushTexture();
void SetName(const std::wstring& name);
std::wstring GetName() const;
public:
CBrushTexture(const std::wstring& strName, WrapMode wrapMode = WrapModeTile);
CBrushTexture(CImage *pImage, WrapMode wrapMode = WrapModeTile);
virtual ~CBrushTexture();
virtual CBrush* Clone() const;
void SetColor1(const CColor& color);
CColor GetColor1() const;
void SetColor2(const CColor& color);
CColor GetColor2() const;
void TranslateTransform(double dX, double dY, MatrixOrder order = MatrixOrderPrepend);
void ScaleTransform(double dX, double dY, MatrixOrder order = MatrixOrderPrepend);
void RotateTransform(double angle, MatrixOrder order = MatrixOrderPrepend);
void GetTransform(CMatrix* matrix) const;
void SetTransform(const CMatrix* matrix);
void SetBounds(const CDoubleRect& rect);
CDoubleRect& GetBounds();
void SetWrapMode(WrapMode wMode);
WrapMode GetWrapMode() const;
public:
CBrushHatch& operator=(const CBrushHatch& other);
CBrushHatch& operator=(CBrushHatch&& other) noexcept;
protected:
/**
* @brief m_wsName - hatch brush pattern name
* (as default - cross)
*
* See all patterns in agg_span_hatch.h, array -
* c_resource_hatches_names.
*/
std::wstring m_wsName;
CColor m_dwColor1{};
CColor m_dwColor2{};
void* GetData();
void* PatternFinalize();
DWORD PatternGetWidth();
DWORD PatternGetHeight();
int PatternGetStride();
public:
CImage* m_pImage;
INT m_bReleaseImage;
WrapMode m_wrapMode;
CMatrix m_mtx;
CDoubleRect m_oBounds{};
};
CColor m_colors[2];
/**
* @class CBrushLinearGradient
*
* brush for drawing gradients, stores information about the gradient.
* According to the pdf documentation, it stores the start and end point
* and color, as well as the linear interpolation of the colors.
*/
class CBrushLinearGradient : public CBrush
{
friend class CGraphics;
bool m_bUseBounds;
CDoubleRect m_oBounds;
public:
CBrushLinearGradient();
CBrushLinearGradient(const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2);
CBrushLinearGradient(const Point& p1, const Point& p2, const CColor& c1, const CColor& c2);
CBrushLinearGradient(const RectF& rect, const CColor& c1, const CColor& c2, float angle, bool isAngleScalable);
CBrushLinearGradient(const Rect& rect, const CColor& c1, const CColor& c2, float angle, bool isAngleScalable);
CBrushLinearGradient(const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode);
CBrushLinearGradient(const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode);
CBrushLinearGradient(const CBrushLinearGradient& other);
CBrushLinearGradient(CBrushLinearGradient&& other) noexcept;
virtual ~CBrushLinearGradient();
BYTE Alpha;
};
Status GetLinearColors(CColor* colors) const;
Status GetRectangle(Rect *rect) const;
Status GetRectangle(RectF *rect) const;
Status GetTransform(CMatrix* matrix) const;
Status MultiplyTransform(const CMatrix *matrix, MatrixOrder order = MatrixOrderPrepend);
Status ResetTransform();
Status RotateTransform(float angle, MatrixOrder order = MatrixOrderPrepend );
Status ScaleTransform(float sx, float sy, MatrixOrder order = MatrixOrderPrepend );
void SetWrapMode(WrapMode mode);
WrapMode GetWrapMode() const;
Status SetInterpolationColors(const CColor *presetColors, const float *blendPositions, int count);
Status GetInterpolationColors(CColor *presetColors, float *blendPositions, int count) const;
int GetInterpolationColorsCount() const;
void GetSubColor(int index, CColor* color, float* position) const;
void SetRelativeCoords(bool relative);
bool IsRelativeCoords() const;
bool IsAngleScalable() const;
bool IsRectable() const;
float GetAngle() const;
void SetBounds(const CDoubleRect& rect);
CDoubleRect& GetBounds();
CBrushLinearGradient& operator=(const CBrushLinearGradient& other);
CBrushLinearGradient& operator=(CBrushLinearGradient&& other) noexcept;
NSStructures::GradientInfo m_oGradientInfo{};
protected:
CColor m_arColors[2];
PointF m_arPoints[2];
struct TSubColor
{
CColor color{};
float position = 0;
};
std::vector<TSubColor> m_arSubColors;
CMatrix m_Matrix{};
/**
* @brief m_angle - rotation angle of line p1 - p2 (measured in degrees)
*/
float m_fAngle = 0;
CDoubleRect m_oBounds{};
/**
* @brief m_eWrapMode - Used to determine the rotation of the image tiles
* (by default, we do not change the position).
*/
WrapMode m_eWrap = Aggplus::WrapModeTile;
/**
* @brief m_bAngleScalable - whether to scale the rotation angle relative
* to the given points
*
* calculated like this b = arctan(width / height * tan(angle));
*/
bool m_bAngleScalable = false;
/**
* @brief m_bRectable - is the diagonal of a rectangle a guide
*/
bool m_bRectable = false;
/**
* @brief m_bRelativeCoords - are the coordinates of the points calculated
* relative to the resulting primitive
*/
bool m_bRelativeCoords = false;
};
/**
* @class CBrushTexture
*
* A texture brush that is used to draw images on the renderer.
*/
class CBrushTexture : public CBrush
{
friend class CGraphics;
public:
CBrushTexture();
CBrushTexture(const std::wstring& name, WrapMode mode = WrapModeTile);
CBrushTexture(CImage *image, WrapMode mode = WrapModeTile);
CBrushTexture(const CBrushTexture& other);
CBrushTexture(CBrushTexture&& other);
virtual ~CBrushTexture();
void TranslateTransform(double x, double y, MatrixOrder order = MatrixOrderPrepend);
void ScaleTransform(double x, double y, MatrixOrder order = MatrixOrderPrepend);
void RotateTransform(double angle, MatrixOrder order = MatrixOrderPrepend);
void GetTransform(CMatrix* matrix) const;
void SetTransform(const CMatrix* matrix);
void SetWrapMode(WrapMode mode);
WrapMode GetWrapMode() const;
void SetBounds(const CDoubleRect& rect);
CDoubleRect& GetBounds();
void SetReleaseImage(bool isReleaseImage);
bool IsReleaseImage() const;
void SetAlpha(BYTE alpha);
BYTE GetAlpha() const;
void* GetData();
void* PatternFinalize();
DWORD PatternGetWidth();
DWORD PatternGetHeight();
int PatternGetStride();
CBrushTexture& operator=(const CBrushTexture& other);
CBrushTexture& operator=(CBrushTexture&& other);
protected:
CImage* m_pImage{nullptr};
bool m_bReleaseImage = false;
/**
* @brief m_eWrapMode - Used to determine the rotation of the image tiles
* (by default, we do not change the position).
*/
WrapMode m_eWrapMode = WrapModeTile;
CMatrix m_Matrix{};
bool m_bUseBounds = false;
CDoubleRect m_oBounds{};
BYTE m_Alpha = 255;
};
}
#endif // _BUILD_BRUSH_H_

View File

@ -832,7 +832,8 @@ namespace Aggplus
b = ptxBrush->m_oBounds.bottom;
}
CMatrix brushMatrix(ptxBrush->m_mtx);
CMatrix brushMatrix;
ptxBrush->GetTransform(&brushMatrix);
if (ptxBrush->GetWrapMode() == Aggplus::WrapModeClamp)
{
double dScaleX = (r - x) / dwPatternWidth;
@ -1652,11 +1653,11 @@ namespace Aggplus
m_rasterizer.gamma(1.0);
}
#else
agg::rgba8 c1 = agg::rgba8(pBrush->m_dwColor1.GetR(), pBrush->m_dwColor1.GetG(), pBrush->m_dwColor1.GetB(), pBrush->m_dwColor1.GetA());
agg::rgba8 c2 = agg::rgba8(pBrush->m_dwColor2.GetR(), pBrush->m_dwColor2.GetG(), pBrush->m_dwColor2.GetB(), pBrush->m_dwColor2.GetA());
agg::rgba8 c1 = agg::rgba8(pBrush->GetColor1().GetR(), pBrush->GetColor1().GetG(), pBrush->GetColor1().GetB(), pBrush->GetColor1().GetA());
agg::rgba8 c2 = agg::rgba8(pBrush->GetColor2().GetR(), pBrush->GetColor2().GetG(), pBrush->GetColor2().GetB(), pBrush->GetColor2().GetA());
BYTE* pPattern = new BYTE[HATCH_TX_SIZE * HATCH_TX_SIZE * 4];
agg::GetHatchPattern(pBrush->m_name, (agg::rgba8*)pPattern, c1, c2);
agg::GetHatchPattern(pBrush->GetName(), (agg::rgba8*)pPattern, c1, c2);
agg::trans_affine mtx_Work(m_oTransform.m_internal->m_agg_mtx);
if (m_dDpiTile > 1)
@ -2049,22 +2050,22 @@ namespace Aggplus
if(pImgBuff && dwImgWidth && dwImgHeight)
{
Aggplus::WrapMode wrapmode = ptxBrush->m_wrapMode;
Aggplus::CMatrix matrix = ptxBrush->m_mtx;
Aggplus::WrapMode wrapmode = ptxBrush->m_eWrapMode;
Aggplus::CMatrix matrix = ptxBrush->m_Matrix;
if(wrapmode == WrapModeClamp)
{
DoFillPathTextureClampSz2( matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, ptxBrush->Alpha);
DoFillPathTextureClampSz2( matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, ptxBrush->m_Alpha);
}
else
{
if (!m_bSwapRGB)
{
DoFillPathTextureClampSz3<agg::pixfmt_bgra32>(matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, wrapmode, ptxBrush->Alpha);
DoFillPathTextureClampSz3<agg::pixfmt_bgra32>(matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, wrapmode, ptxBrush->m_Alpha);
}
else
{
DoFillPathTextureClampSz3<agg::pixfmt_rgba32>(matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, wrapmode, ptxBrush->Alpha);
DoFillPathTextureClampSz3<agg::pixfmt_rgba32>(matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, wrapmode, ptxBrush->m_Alpha);
}
}
}

View File

@ -48,7 +48,7 @@ namespace Aggplus
CGraphicsPath::CGraphicsPath(CGraphicsPath&& other) noexcept
{
*this = other;
*this = std::move(other);
}
CGraphicsPath::CGraphicsPath(const std::vector<CGraphicsPath>& paths) noexcept : CGraphicsPath()

View File

@ -94,7 +94,7 @@ Aggplus::CBrush* CGraphicsRenderer::CreateBrush(NSStructures::CBrush* pBrush)
Aggplus::CColor o1((BYTE)(pBrush->Alpha1 * m_dGlobalAlpha), pBrush->Color1, bIsSwappedRGB);
Aggplus::CColor o2((BYTE)(pBrush->Alpha2 * m_dGlobalAlpha), pBrush->Color2, bIsSwappedRGB);
Aggplus::CBrushLinearGradient* pNew = new Aggplus::CBrushLinearGradient( Aggplus::RectF(0.0f, 0.0f, 1.0f, 1.0f), o1, o2, (float)pBrush->LinearAngle, TRUE );
Aggplus::CBrushLinearGradient* pNew = new Aggplus::CBrushLinearGradient(Aggplus::RectF(0.0f, 0.0f, 1.0f, 1.0f), o1, o2, (float)pBrush->LinearAngle, true);
if( pNew )
{
pNew->SetRelativeCoords( TRUE );
@ -180,11 +180,11 @@ Aggplus::CBrush* CGraphicsRenderer::CreateBrush(NSStructures::CBrush* pBrush)
Aggplus::CColor o2((BYTE)(pBrush->Alpha2 * m_dGlobalAlpha), pBrush->Color2, bIsSwappedRGB);
Aggplus::CBrushHatch* pNew = new Aggplus::CBrushHatch();
pNew->m_dwColor1 = o1;
pNew->m_dwColor2 = o2;
pNew->m_name = pBrush->TexturePath;
pNew->SetColor1(o1);
pNew->SetColor2(o2);
pNew->SetName(pBrush->TexturePath);
pNew->Bounds = pBrush->Bounds;
pNew->SetBounds(pBrush->Bounds);
return pNew;
}
@ -996,7 +996,7 @@ HRESULT CGraphicsRenderer::DrawPath(const LONG& nType)
pImage->Create(oFrame.get_Data(), oFrame.get_Width(), oFrame.get_Height(), oFrame.get_Stride());
oFrame.ClearNoAttack();
pTextureBrush = new Aggplus::CBrushTexture(pImage, oMode);
pTextureBrush->m_bReleaseImage = TRUE;
pTextureBrush->SetReleaseImage(true);
}
else
RELEASEARRAYOBJECTS(pImageData);
@ -1018,15 +1018,14 @@ HRESULT CGraphicsRenderer::DrawPath(const LONG& nType)
{
pTextureBrush->SetTransform(&m_oBrush.Transform);
pTextureBrush->Alpha = (BYTE)m_oBrush.TextureAlpha;
pTextureBrush->SetAlpha(static_cast<BYTE>(m_oBrush.TextureAlpha));
if (m_oBrush.Rectable == 1)
{
pTextureBrush->m_bUseBounds = true;
pTextureBrush->m_oBounds.left = m_oBrush.Rect.X;
pTextureBrush->m_oBounds.top = m_oBrush.Rect.Y;
pTextureBrush->m_oBounds.right = pTextureBrush->m_oBounds.left + m_oBrush.Rect.Width;
pTextureBrush->m_oBounds.bottom = pTextureBrush->m_oBounds.top + m_oBrush.Rect.Height;
pTextureBrush->SetBounds({m_oBrush.Rect.X,
m_oBrush.Rect.Y,
m_oBrush.Rect.X + m_oBrush.Rect.Width,
m_oBrush.Rect.Y + m_oBrush.Rect.Height});
}
}

View File

@ -51,6 +51,16 @@ namespace Aggplus
Create(filename);
}
CImage::CImage(const CImage& other)
{
*this = other;
}
CImage::CImage(CImage&& other)
{
*this = std::move(other);
}
CImage::~CImage()
{
Destroy();
@ -136,6 +146,46 @@ namespace Aggplus
m_bExternalBuffer = false;
}
CImage& CImage::operator=(const CImage& other)
{
if (this == &other)
return *this;
m_Status = other.m_Status;
m_dwHeight = other.m_dwHeight;
m_dwWidth = other.m_dwWidth;
m_nStride = other.m_nStride;
m_bExternalBuffer = other.m_bExternalBuffer;
size_t size_of_data = m_dwHeight * m_nStride > 0 ? m_nStride : -m_nStride;
m_pImgData = new BYTE[size_of_data];
memcpy(m_pImgData, other.m_pImgData, size_of_data);
return *this;
}
CImage& CImage::operator=(CImage&& other)
{
if (this == &other)
return *this;
m_Status = other.m_Status;
m_dwHeight = other.m_dwHeight;
m_dwWidth = other.m_dwWidth;
m_nStride = other.m_nStride;
m_bExternalBuffer = other.m_bExternalBuffer;
m_pImgData = other.m_pImgData;
other.m_pImgData = nullptr;
return *this;
}
DWORD CImage::GetWidth() const { return(m_dwWidth); }
DWORD CImage::GetHeight() const { return(m_dwHeight); }
long CImage::GetStride() const { return(m_nStride); }
@ -146,10 +196,10 @@ namespace Aggplus
////////////////////////////////////////////////////////////////////////////////////////
CBitmap::CBitmap(LONG width, LONG height, PixelFormat format) : CImage()
{
if(width <= 0 || height <= 0)
{
m_Status=InvalidParameter;
return;
if(width <= 0 || height <= 0)
{
m_Status=InvalidParameter;
return;
}
LONG lSize = 4 * width * height;
@ -168,15 +218,15 @@ namespace Aggplus
CBitmap::CBitmap(LONG width, LONG height, LONG stride, PixelFormat format, BYTE* scan0) : CImage()
{
//Warning! This is not Gdiplus behavior; it returns Ok!
if(width <= 0 || height <= 0 || stride == 0)
{
m_Status = InvalidParameter;
return;
if(width <= 0 || height <= 0 || stride == 0)
{
m_Status = InvalidParameter;
return;
}
m_bExternalBuffer = true;
if (stride > 0)
if (stride > 0)
{
m_pImgData = scan0;
}
@ -184,7 +234,7 @@ namespace Aggplus
{
m_pImgData = scan0 + (height - 1) * (-stride);
}
m_dwWidth = width;
m_dwHeight = height;
m_nStride = stride;

View File

@ -49,6 +49,8 @@ public:
public:
CImage();
CImage(const std::wstring& filename);
CImage(const CImage& other);
CImage(CImage&& other);
virtual ~CImage();
DWORD GetWidth() const;
@ -64,6 +66,9 @@ public:
bool SaveFile(const std::wstring& strFileName, UINT nFileType);
void Destroy();
CImage& operator=(const CImage& other);
CImage& operator=(CImage&& other);
protected:
Status m_Status;

View File

@ -30,127 +30,133 @@
*
*/
#include "Matrix_private.h"
#include <utility>
namespace Aggplus
{
CMatrix::CMatrix(double m11, double m12, double m21, double m22, double dx, double dy)
CMatrix::CMatrix(double m11, double m12, double m21, double m22, double dx, double dy)
{
m_internal = new CMatrix_private();
m_internal->m_agg_mtx.sx = m11;
m_internal->m_agg_mtx.shy = m12;
m_internal->m_agg_mtx.shx = m21;
m_internal->m_agg_mtx.sy = m22;
m_internal->m_agg_mtx.tx = dx;
m_internal->m_agg_mtx.ty = dy;
m_internal = new CMatrix_private();
m_internal->m_agg_mtx.sx = m11;
m_internal->m_agg_mtx.shy = m12;
m_internal->m_agg_mtx.shx = m21;
m_internal->m_agg_mtx.sy = m22;
m_internal->m_agg_mtx.tx = dx;
m_internal->m_agg_mtx.ty = dy;
}
CMatrix::CMatrix(const CMatrix& oSrc)
{
m_internal = new CMatrix_private();
m_internal->m_agg_mtx = oSrc.m_internal->m_agg_mtx;
}
CMatrix::CMatrix()
CMatrix::CMatrix()
{
m_internal = new CMatrix_private();
m_internal = new CMatrix_private();
}
CMatrix::CMatrix(const CMatrix& other)
{
*this = other;
}
CMatrix::CMatrix(CMatrix&& other)
{
*this = std::move(other);
}
CMatrix::~CMatrix()
{
RELEASEOBJECT(m_internal);
RELEASEOBJECT(m_internal);
}
void CMatrix::Translate(double offsetX, double offsetY, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_translation(offsetX, offsetY));
}
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_translation(offsetX, offsetY));
}
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_translation(offsetX, offsetY));
else
m_internal->m_agg_mtx.multiply(agg::trans_affine_translation(offsetX, offsetY));
}
void CMatrix::Scale(double scaleX, double scaleY, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_scaling(scaleX, scaleY));
}
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_scaling(scaleX, scaleY));
}
{
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_scaling(scaleX, scaleY));
else
m_internal->m_agg_mtx.multiply(agg::trans_affine_scaling(scaleX, scaleY));
}
void CMatrix::Shear(double shearX, double shearY, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_skewing(shearX, shearY));
}
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_skewing(shearX, shearY));
}
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_skewing(shearX, shearY));
else
m_internal->m_agg_mtx.multiply(agg::trans_affine_skewing(shearX, shearY));
}
double CMatrix::Determinant() const
{
return m_internal->m_agg_mtx.determinant();
}
void CMatrix::TransformVectors(PointF* pts, int count) const
{
// Store matrix to an array [6] of double
double M[6]; m_internal->m_agg_mtx.store_to(M);
double M[6];
m_internal->m_agg_mtx.store_to(M);
for (int i = 0; i < count; ++i)
for (int i = 0; i < count; ++i)
{
double x = pts[i].X;
double y = pts[i].Y;
m_internal->m_agg_mtx.transform(&x, &y);
pts[i].X = (float)(x-M[4]);
pts[i].Y = (float)(y-M[5]);
double x = pts[i].X;
double y = pts[i].Y;
m_internal->m_agg_mtx.transform(&x, &y);
pts[i].X = static_cast<float>(x-M[4]);
pts[i].Y = static_cast<float>(y-M[5]);
}
}
void CMatrix::TransformPoints(PointF* pts, int count) const
{
for (int i = 0; i < count; ++i)
for (int i = 0; i < count; ++i)
{
double x = pts[i].X;
double y = pts[i].Y;
m_internal->m_agg_mtx.transform(&x, &y);
pts[i].X = (float)x;
pts[i].Y = (float)y;
m_internal->m_agg_mtx.transform(&x, &y);
pts[i].X = static_cast<float>(x);
pts[i].Y = static_cast<float>(y);
}
}
void CMatrix::TransformPoint(double& x, double& y) const
{
m_internal->m_agg_mtx.transform(&x, &y);
m_internal->m_agg_mtx.transform(&x, &y);
}
void CMatrix::TransformPoints(PointF* dst, const PointF* src, int count) const
{
agg::trans_affine& m = m_internal->m_agg_mtx;
for(int i = 0; i < count; ++i)
{
double x = src[i].X * m.sx + src[i].Y * m.shx + m.tx;
double y = src[i].Y * m.sy + src[i].X * m.shy + m.ty;
dst[i].X = static_cast<float>(x);
dst[i].Y = static_cast<float>(y);
}
}
void CMatrix::Rotate(double angle, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
void CMatrix::RotateAt(double angle, const PointF &center, MatrixOrder order)
{
Translate(-center.X, -center.Y, order);
if(order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
if(order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
else
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
Translate(center.X, center.Y, order);
return;
}
@ -158,168 +164,169 @@ namespace Aggplus
void CMatrix::RotateAt(double angle, double x, double y, MatrixOrder order)
{
Translate(-x, -y, order);
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
else
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
Translate(x, y, order);
}
void CMatrix::Multiply(const CMatrix* matrix, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(matrix->m_internal->m_agg_mtx);
}
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(matrix->m_internal->m_agg_mtx);
else
{
m_internal->m_agg_mtx.multiply(matrix->m_internal->m_agg_mtx);
}
m_internal->m_agg_mtx.multiply(matrix->m_internal->m_agg_mtx);
}
double CMatrix::OffsetX() const
{
return m_internal->m_agg_mtx.tx;
return m_internal->m_agg_mtx.tx;
}
double CMatrix::OffsetY() const
{
return m_internal->m_agg_mtx.ty;
return m_internal->m_agg_mtx.ty;
}
double CMatrix::sx() const
{
return m_internal->m_agg_mtx.sx;
}
double CMatrix::sy() const
{
return m_internal->m_agg_mtx.sy;
}
double CMatrix::shx() const
{
return m_internal->m_agg_mtx.shx;
}
double CMatrix::shy() const
{
return m_internal->m_agg_mtx.shy;
}
double CMatrix::tx() const
{
return m_internal->m_agg_mtx.tx;
}
double CMatrix::ty() const
{
return m_internal->m_agg_mtx.ty;
}
double CMatrix::rotation()
{
return m_internal->m_agg_mtx.rotation();
}
void CMatrix::SetElements(const double& sx, const double& shy, const double& shx, const double& sy, const double& tx, const double& ty)
{
m_internal->m_agg_mtx.sx = sx;
m_internal->m_agg_mtx.shy = shy;
m_internal->m_agg_mtx.shx = shx;
m_internal->m_agg_mtx.sy = sy;
m_internal->m_agg_mtx.tx = tx;
m_internal->m_agg_mtx.ty = ty;
}
Status CMatrix::GetElements(REAL* m) const
double CMatrix::sx() const
{
double M[6]; m_internal->m_agg_mtx.store_to(M);
m[0]=(REAL)M[0];
m[1]=(REAL)M[1];
m[2]=(REAL)M[2];
m[3]=(REAL)M[3];
m[4]=(REAL)M[4];
m[5]=(REAL)M[5];
return m_internal->m_agg_mtx.sx;
}
double CMatrix::sy() const
{
return m_internal->m_agg_mtx.sy;
}
double CMatrix::shx() const
{
return m_internal->m_agg_mtx.shx;
}
double CMatrix::shy() const
{
return m_internal->m_agg_mtx.shy;
}
double CMatrix::tx() const
{
return m_internal->m_agg_mtx.tx;
}
double CMatrix::ty() const
{
return m_internal->m_agg_mtx.ty;
}
double CMatrix::rotation()
{
return m_internal->m_agg_mtx.rotation();
}
void CMatrix::SetElements(const double& sx, const double& shy, const double& shx,
const double& sy, const double& tx, const double& ty)
{
m_internal->m_agg_mtx.sx = sx;
m_internal->m_agg_mtx.shy = shy;
m_internal->m_agg_mtx.shx = shx;
m_internal->m_agg_mtx.sy = sy;
m_internal->m_agg_mtx.tx = tx;
m_internal->m_agg_mtx.ty = ty;
}
Status CMatrix::GetElements(float* m) const
{
double M[6];
m_internal->m_agg_mtx.store_to(M);
m[0] = static_cast<float>(M[0]);
m[1] = static_cast<float>(M[1]);
m[2] = static_cast<float>(M[2]);
m[3] = static_cast<float>(M[3]);
m[4] = static_cast<float>(M[4]);
m[5] = static_cast<float>(M[5]);
return Ok;
}
Status CMatrix::GetElements(double* m) const
{
m_internal->m_agg_mtx.store_to(m);
m_internal->m_agg_mtx.store_to(m);
return Ok;
}
void CMatrix::Reset()
{
m_internal->m_agg_mtx.reset();
m_internal->m_agg_mtx.reset();
}
double CMatrix::Determinant() const
bool CMatrix::IsIdentity(const double& eps) const
{
return m_internal->m_agg_mtx.determinant();
}
return m_internal->m_agg_mtx.is_identity(eps);
}
const CMatrix& CMatrix::operator=(const CMatrix& Src)
bool CMatrix::IsIdentity2(const double& eps) const
{
m_internal->m_agg_mtx = Src.m_internal->m_agg_mtx;
return *this;
agg::trans_affine& m = m_internal->m_agg_mtx;
return agg::is_equal_eps(m.sx, 1.0, eps) &&
agg::is_equal_eps(m.shy, 0.0, eps) &&
agg::is_equal_eps(m.shx, 0.0, eps) &&
agg::is_equal_eps(m.sy, 1.0, eps);
}
bool CMatrix::IsEqual(const CMatrix* mm1, const CMatrix* mm2, const double& eps, bool bIsOnlyMain)
{
agg::trans_affine& m1 = mm1->m_internal->m_agg_mtx;
agg::trans_affine& m2 = mm2->m_internal->m_agg_mtx;
bool bMain = fabs(m1.sx - m2.sx) < eps &&
fabs(m1.sy - m2.sy) < eps &&
fabs(m1.shx - m2.shx) < eps &&
fabs(m1.shy - m2.shy) < eps;
if (!bMain || bIsOnlyMain)
return bMain;
return fabs(m1.tx - m2.tx) < eps && fabs(m1.ty - m2.ty) < eps;
}
Status CMatrix::Invert()
{
double d = m_internal->m_agg_mtx.determinant();
if (0.0001 >= fabs(d))
double d = m_internal->m_agg_mtx.determinant();
if (0.0001 >= fabs(d))
return InvalidParameter;
m_internal->m_agg_mtx.invert();
m_internal->m_agg_mtx.invert();
return Ok;
}
//Temp
//Used in X_BrushLinearGradient constructor
double CMatrix::z_Rotation() const
{
return agg::rad2deg(m_internal->m_agg_mtx.rotation());
}
void CMatrix::TransformPoints( PointF* dst, const PointF* src, int count ) const
double CMatrix::z_Rotation() const
{
agg::trans_affine& m = m_internal->m_agg_mtx;
for(int i = 0; i < count; ++i)
{
double x = src[i].X * m.sx + src[i].Y * m.shx + m.tx;
double y = src[i].Y * m.sy + src[i].X * m.shy + m.ty;
dst[i].X = (float)x;
dst[i].Y = (float)y;
}
return agg::rad2deg(m_internal->m_agg_mtx.rotation());
}
bool CMatrix::IsIdentity(const double& eps) const
const CMatrix& CMatrix::operator=(const CMatrix& other)
{
return m_internal->m_agg_mtx.is_identity(eps);
if (this == &other)
return *this;
m_internal = new CMatrix_private();
m_internal->m_agg_mtx = other.m_internal->m_agg_mtx;
return *this;
}
bool CMatrix::IsIdentity2(const double& eps) const
CMatrix& CMatrix::operator=(CMatrix&& other)
{
agg::trans_affine& m = m_internal->m_agg_mtx;
return agg::is_equal_eps(m.sx, 1.0, eps) &&
agg::is_equal_eps(m.shy, 0.0, eps) &&
agg::is_equal_eps(m.shx, 0.0, eps) &&
agg::is_equal_eps(m.sy, 1.0, eps);
if (this == &other)
return *this;
m_internal = other.m_internal;
other.m_internal = nullptr;
return *this;
}
bool CMatrix::IsEqual(const CMatrix* mm1, const CMatrix* mm2, const double& eps, bool bIsOnlyMain)
{
agg::trans_affine& m1 = mm1->m_internal->m_agg_mtx;
agg::trans_affine& m2 = mm2->m_internal->m_agg_mtx;
bool bMain = fabs(m1.sx - m2.sx) < eps &&
fabs(m1.sy - m2.sy) < eps &&
fabs(m1.shx - m2.shx) < eps &&
fabs(m1.shy - m2.shy) < eps;
if (!bMain || bIsOnlyMain)
return bMain;
return fabs(m1.tx - m2.tx) < eps && fabs(m1.ty - m2.ty) < eps;
}
}

View File

@ -37,62 +37,62 @@
namespace Aggplus
{
class CMatrix_private;
class GRAPHICS_DECL CMatrix
{
public:
CMatrix(double m11, double m12, double m21, double m22, double dx, double dy);
CMatrix();
CMatrix(const CMatrix& oSrc);
class CMatrix_private;
class GRAPHICS_DECL CMatrix
{
public:
CMatrix();
CMatrix(double m11, double m12, double m21, double m22, double dx, double dy);
CMatrix(const CMatrix& other);
CMatrix(CMatrix&& other);
~CMatrix();
~CMatrix();
void Translate(double offsetX, double offsetY, MatrixOrder order = MatrixOrderPrepend);
void Scale(double scaleX, double scaleY, MatrixOrder order = MatrixOrderPrepend);
void Shear(double shearX, double shearY, MatrixOrder order = MatrixOrderPrepend);
double Determinant() const;
void Translate(double offsetX, double offsetY, MatrixOrder order = MatrixOrderPrepend);
void Scale(double scaleX, double scaleY, MatrixOrder order = MatrixOrderPrepend);
void Shear(double shearX, double shearY, MatrixOrder order = MatrixOrderPrepend);
double Determinant() const;
void TransformVectors(PointF* pts, int count) const;
void TransformPoints(PointF* pts, int count) const;
void TransformPoint(double& x, double& y) const;
void TransformPoints(PointF* dst, const PointF* src, int count) const;
void TransformVectors(PointF* pts, int count) const;
void TransformPoints(PointF* pts, int count) const;
void TransformPoint(double& x, double& y) const;
void TransformPoints(PointF* dst, const PointF* src, int count) const;
void Rotate(double angle, MatrixOrder order = MatrixOrderPrepend);
void RotateAt(double angle, const PointF &center, MatrixOrder order = MatrixOrderPrepend);
void RotateAt(double angle, double x, double y, MatrixOrder order = MatrixOrderPrepend);
void Rotate(double angle, MatrixOrder order = MatrixOrderPrepend);
void RotateAt(double angle, const PointF &center, MatrixOrder order = MatrixOrderPrepend);
void RotateAt(double angle, double x, double y, MatrixOrder order = MatrixOrderPrepend);
void Multiply(const CMatrix* matrix, MatrixOrder order = MatrixOrderPrepend);
void Multiply(const CMatrix* matrix, MatrixOrder order = MatrixOrderPrepend);
double OffsetX() const;
double OffsetY() const;
double OffsetX() const;
double OffsetY() const;
double sx() const;
double sy() const;
double shx() const;
double shy() const;
double tx() const;
double ty() const;
double rotation();
double sx() const;
double sy() const;
double shx() const;
double shy() const;
double tx() const;
double ty() const;
double rotation();
void SetElements(const double& sx, const double& shy, const double& shx, const double& sy, const double& tx = 0, const double& ty = 0);
void SetElements(const double& sx, const double& shy, const double& shx, const double& sy, const double& tx = 0, const double& ty = 0);
Status GetElements(float* m) const;
Status GetElements(double* m) const;
Status GetElements(float* m) const;
Status GetElements(double* m) const;
void Reset();
bool IsIdentity(const double& eps = 0.00001) const;
bool IsIdentity2(const double& eps = 0.00001) const;
void Reset();
bool IsIdentity(const double& eps = 0.00001) const;
bool IsIdentity2(const double& eps = 0.00001) const;
static bool IsEqual(const CMatrix* m1, const CMatrix* m2, const double& eps = 0.001, bool bIsOnlyMain = false);
static bool IsEqual(const CMatrix* m1, const CMatrix* m2, const double& eps = 0.001, bool bIsOnlyMain = false);
Status Invert();
const CMatrix& operator=(const CMatrix& Src);
double z_Rotation() const;
Status Invert();
const CMatrix& operator=(const CMatrix& other);
CMatrix& operator=(CMatrix&& other);
double z_Rotation() const;
public:
CMatrix_private* m_internal;
};
public:
CMatrix_private* m_internal;
};
}
#endif // _BUILD_MATRIX_H_

View File

@ -686,7 +686,6 @@ const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetDV() { return m_wsDV; }
const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetT() { return m_wsT; }
const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetFontName() { return m_wsFN; }
const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetFontKey() { return m_wsFK; }
const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::GetOMetadata() { return m_wsOMetadata; }
const std::vector<double>& CAnnotFieldInfo::CWidgetAnnotPr::GetTC() { return m_arrTC; }
const std::vector<double>& CAnnotFieldInfo::CWidgetAnnotPr::GetBC() { return m_arrBC; }
const std::vector<double>& CAnnotFieldInfo::CWidgetAnnotPr::GetBG() { return m_arrBG; }
@ -887,8 +886,6 @@ void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader
m_nParentID = pReader->ReadInt();
if (nFlags & (1 << 18))
m_wsT = pReader->ReadString();
if (nFlags & (1 << 20))
m_wsOMetadata = pReader->ReadString();
// Action
int nAction = pReader->ReadInt();
@ -985,7 +982,7 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf
m_wsV = pReader->ReadString();
if (nFlags & (1 << 10))
m_nMaxLen = pReader->ReadInt();
if (nFlags & (1 << 11))
if (nWidgetFlag & (1 << 25))
m_wsRV = pReader->ReadString();
if (nFlags & (1 << 12))
m_wsAPV = pReader->ReadString();
@ -1104,34 +1101,6 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil
for (int i = 0; i < n; ++i)
pParent->arrV.push_back(pReader->ReadString());
}
if (nFlags & (1 << 6))
{
int n = pReader->ReadInt();
pParent->arrOpt.reserve(n);
for (int i = 0; i < n; ++i)
{
std::wstring s1 = pReader->ReadString();
std::wstring s2 = pReader->ReadString();
pParent->arrOpt.push_back(std::make_pair(s1, s2));
}
}
if (nFlags & (1 << 7))
pParent->nFieldFlag = pReader->ReadInt();
if (nFlags & (1 << 8))
{
// Action
int nAction = pReader->ReadInt();
for (int i = 0; i < nAction; ++i)
{
std::wstring wsType = pReader->ReadString();
CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pA = ReadAction(pReader);
if (pA)
{
pA->wsType = wsType;
pParent->arrAction.push_back(pA);
}
}
}
m_arrParents.push_back(pParent);
}

View File

@ -194,7 +194,6 @@ public:
const std::wstring& GetT();
const std::wstring& GetFontName();
const std::wstring& GetFontKey();
const std::wstring& GetOMetadata();
const std::vector<double>& GetTC();
const std::vector<double>& GetBC();
const std::vector<double>& GetBG();
@ -224,7 +223,6 @@ public:
std::wstring m_wsT;
std::wstring m_wsFN;
std::wstring m_wsFK;
std::wstring m_wsOMetadata;
std::vector<double> m_arrTC;
std::vector<double> m_arrBC;
std::vector<double> m_arrBG;
@ -568,14 +566,11 @@ public:
int nID;
int nFlags;
int nParentID;
int nFieldFlag;
std::wstring sName;
std::wstring sV;
std::wstring sDV;
std::vector<int> arrI;
std::vector<std::wstring> arrV;
std::vector<CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget*> arrAction;
std::vector< std::pair<std::wstring, std::wstring> > arrOpt;
};
CWidgetsInfo();

View File

@ -701,6 +701,7 @@ namespace NSFonts
virtual void Initialize() = 0;
virtual void SetOwnerCache(IFontsCache* pCache) = 0;
virtual void CreateOwnerCache(const int& nCacheSize = -1);
virtual void ClearOwnerCache() = 0;
virtual void AfterLoad() = 0;

View File

@ -110,11 +110,20 @@ namespace NSImages
#ifndef GRAPHICS_DISABLE_METAFILE
namespace MetaFile
{
const int c_lMetaWmf = 0x01;
const int c_lMetaEmf = 0x02;
const int c_lMetaSvg = 0x04;
const int c_lMetaSvm = 0x05;
/**
* @brief Meta file extension constants
*/
const long c_lMetaWmf = 0x0001;
const long c_lMetaEmf = 0x0002;
const long c_lMetaSvg = 0x0004;
const long c_lMetaSvm = 0x0005;
/**
* @interface IMetaFile
*
* The interface provides various options for loading a metafile and saving it
* in another format.
*/
class GRAPHICS_DECL IMetaFile : public NSBase::CBaseRefCounter
{
public:
@ -124,23 +133,20 @@ namespace MetaFile
virtual bool LoadFromFile(const wchar_t* wsFilePath) = 0;
virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) = 0;
virtual bool LoadFromString(const std::wstring& data) = 0;
virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) = 0;
virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY,
double dWidth, double dHeight, const wchar_t* wsXmlFilePath = NULL) = 0;
virtual void Close() = 0;
virtual void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH) = 0;
virtual int GetType() = 0;
virtual void ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1) = 0;
virtual void ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1, const wchar_t* wsXmlOutFile = NULL) = 0;
virtual NSFonts::IFontManager* get_FontManager() = 0;
virtual std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0) = 0;
virtual void SetTempDirectory(const std::wstring& dir) = 0;
//Для тестов
#ifdef METAFILE_SUPPORT_WMF_EMF
virtual void ConvertToXml(const wchar_t *wsFilePath) = 0;
virtual void ConvertToXmlAndRaster(const wchar_t *wsXmlFilePath, const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1) = 0;
virtual bool LoadFromXmlFile(const wchar_t* wsFilePath) = 0;
virtual void ConvertToXml(const wchar_t *wsFilePath) = 0;
virtual void ConvertToEmf(const wchar_t *wsFilePath) = 0;
#endif
};
GRAPHICS_DECL IMetaFile* Create(NSFonts::IApplicationFonts *pAppFonts);

View File

@ -568,53 +568,9 @@ CFile.prototype["getInteractiveFormsInfo"] = function()
if (flags & (1 << 6))
{
let n = reader.readInt();
rec["opt"] = [];
rec["Opt"] = [];
for (let i = 0; i < n; ++i)
{
let opt1 = reader.readString();
let opt2 = reader.readString();
if (opt1 == "")
rec["opt"].push(opt2);
else
rec["opt"].push([opt2, opt1]);
}
}
if (flags & (1 << 7))
{
rec["flag"] = reader.readInt();
rec["readOnly"] = (rec["flag"] >> 0) & 1; // ReadOnly
rec["required"] = (rec["flag"] >> 1) & 1; // Required
rec["noexport"] = (rec["flag"] >> 2) & 1; // NoExport
rec["NoToggleToOff"] = (rec["flag"] >> 14) & 1; // NoToggleToOff
if ((rec["flag"] >> 15) & 1) // If radiobutton
rec["radiosInUnison"] = (rec["flag"] >> 25) & 1; // RadiosInUnison
else
rec["richText"] = (rec["flag"] >> 25) & 1; // RichText
rec["multiline"] = (rec["flag"] >> 12) & 1; // Multiline
rec["password"] = (rec["flag"] >> 13) & 1; // Password
rec["fileSelect"] = (rec["flag"] >> 20) & 1; // FileSelect
rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck
rec["doNotScroll"] = (rec["flag"] >> 23) & 1; // DoNotScroll
rec["comb"] = (rec["flag"] >> 24) & 1; // Comb
rec["editable"] = (rec["flag"] >> 18) & 1; // Edit
rec["multipleSelection"] = (rec["flag"] >> 21) & 1; // MultiSelect
rec["commitOnSelChange"] = (rec["flag"] >> 26) & 1; // CommitOnSelChange
}
if (flags & (1 << 8))
{
let nAction = reader.readInt();
if (nAction > 0)
rec["AA"] = {};
for (let i = 0; i < nAction; ++i)
{
let AAType = reader.readString();
rec["AA"][AAType] = {};
readAction(reader, rec["AA"][AAType]);
}
rec["Opt"].push(reader.readString());
}
res["Parents"].push(rec);
}
@ -645,12 +601,9 @@ CFile.prototype["getInteractiveFormsInfo"] = function()
rec["alignment"] = reader.readByte();
rec["flag"] = reader.readInt();
// 12.7.3.1
if (rec["flag"] >= 0)
{
rec["readOnly"] = (rec["flag"] >> 0) & 1; // ReadOnly
rec["required"] = (rec["flag"] >> 1) & 1; // Required
rec["noexport"] = (rec["flag"] >> 2) & 1; // NoExport
}
rec["readOnly"] = (rec["flag"] >> 0) & 1; // ReadOnly
rec["required"] = (rec["flag"] >> 1) & 1; // Required
rec["noexport"] = (rec["flag"] >> 2) & 1; // NoExport
let flags = reader.readInt();
// Alternative field name, used in tooltip and error messages - TU
if (flags & (1 << 0))
@ -698,8 +651,6 @@ CFile.prototype["getInteractiveFormsInfo"] = function()
rec["name"] = reader.readString();
if (flags & (1 << 19))
rec["font"]["AP"] = reader.readString();
if (flags & (1 << 20))
rec["meta"] = reader.readString();
// Action
let nAction = reader.readInt();
if (nAction > 0)
@ -759,11 +710,8 @@ CFile.prototype["getInteractiveFormsInfo"] = function()
if (flags & (1 << 14))
rec["ExportValue"] = reader.readString();
// 12.7.4.2.1
if (rec["flag"] >= 0)
{
rec["NoToggleToOff"] = (rec["flag"] >> 14) & 1; // NoToggleToOff
rec["radiosInUnison"] = (rec["flag"] >> 25) & 1; // RadiosInUnison
}
rec["NoToggleToOff"] = (rec["flag"] >> 14) & 1; // NoToggleToOff
rec["radiosInUnison"] = (rec["flag"] >> 25) & 1; // RadiosInUnison
}
else if (rec["type"] == 30)
{
@ -771,19 +719,16 @@ CFile.prototype["getInteractiveFormsInfo"] = function()
rec["value"] = reader.readString();
if (flags & (1 << 10))
rec["maxLen"] = reader.readInt();
if (flags & (1 << 11))
if (rec["flag"] & (1 << 25))
rec["richValue"] = reader.readString();
// 12.7.4.3
if (rec["flag"] >= 0)
{
rec["multiline"] = (rec["flag"] >> 12) & 1; // Multiline
rec["password"] = (rec["flag"] >> 13) & 1; // Password
rec["fileSelect"] = (rec["flag"] >> 20) & 1; // FileSelect
rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck
rec["doNotScroll"] = (rec["flag"] >> 23) & 1; // DoNotScroll
rec["comb"] = (rec["flag"] >> 24) & 1; // Comb
rec["richText"] = (rec["flag"] >> 25) & 1; // RichText
}
rec["multiline"] = (rec["flag"] >> 12) & 1; // Multiline
rec["password"] = (rec["flag"] >> 13) & 1; // Password
rec["fileSelect"] = (rec["flag"] >> 20) & 1; // FileSelect
rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck
rec["doNotScroll"] = (rec["flag"] >> 23) & 1; // DoNotScroll
rec["comb"] = (rec["flag"] >> 24) & 1; // Comb
rec["richText"] = (rec["flag"] >> 25) & 1; // RichText
}
else if (rec["type"] == 31 || rec["type"] == 32)
{
@ -820,20 +765,15 @@ CFile.prototype["getInteractiveFormsInfo"] = function()
rec["value"].push(reader.readString());
}
// 12.7.4.4
if (rec["flag"] >= 0)
{
rec["editable"] = (rec["flag"] >> 18) & 1; // Edit
rec["multipleSelection"] = (rec["flag"] >> 21) & 1; // MultiSelect
rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck
rec["commitOnSelChange"] = (rec["flag"] >> 26) & 1; // CommitOnSelChange
}
rec["editable"] = (rec["flag"] >> 18) & 1; // Edit
rec["multipleSelection"] = (rec["flag"] >> 21) & 1; // MultiSelect
rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck
rec["commitOnSelChange"] = (rec["flag"] >> 26) & 1; // CommitOnSelChange
}
else if (rec["type"] == 33)
{
rec["Sig"] = (flags >> 9) & 1;
}
if (rec["flag"] < 0)
delete rec["flag"];
res["Fields"].push(rec);
}

View File

@ -380,36 +380,9 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i)
i += 4;
std::cout << " " << std::string((char*)(pWidgets + i), nPathLength);
i += nPathLength;
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << " " << std::string((char*)(pWidgets + i), nPathLength);
i += nPathLength;
}
std::cout << " ], ";
}
if (nFlags & (1 << 7))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "Ff " << nPathLength;
}
if (nFlags & (1 << 8))
{
int nActLength = READ_INT(pWidgets + i);
i += 4;
for (int j = 0; j < nActLength; ++j)
{
std::cout << std::endl;
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << std::to_string(j) << " Action " << std::string((char*)(pWidgets + i), nPathLength) << ", ";
i += nPathLength;
ReadAction(pWidgets, i);
}
std::cout << std::endl;
}
std::cout << std::endl;
}
@ -569,13 +542,6 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i)
std::cout << "Font button " << std::string((char*)(pWidgets + i), nPathLength) << ", ";
i += nPathLength;
}
if (nFlags & (1 << 20))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
std::cout << "OMetadata " << std::string((char*)(pWidgets + i), nPathLength) << ", ";
i += nPathLength;
}
//Action
@ -703,7 +669,7 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i)
i += 4;
std::cout << "MaxLen " << nPathLength << ", ";
}
if (nFlags & (1 << 11))
if (nFieldFlag & (1 << 25))
{
nPathLength = READ_INT(pWidgets + i);
i += 4;
@ -840,7 +806,7 @@ void ReadAnnotAP(BYTE* pWidgetsAP, int& i)
i += 1;
std::string arrBlendMode[] = { "Normal", "Multiply", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", "ColorBurn", "HardLight",
"SoftLight", "Difference", "Exclusion", "Hue", "Saturation", "Color", "Luminosity" };
std::cout << "Type " << arrBlendMode[nPathLength];
std::cout << "Type " << arrBlendMode[nPathLength] << ", ";
}
std::cout << std::endl;
}
@ -1124,7 +1090,7 @@ int main(int argc, char* argv[])
}
// GLYPHS
if (false && nPagesCount > 0)
if (true && nPagesCount > 0)
{
BYTE* pGlyphs = GetGlyphs(pGrFile, nTestPage);
nLength = READ_INT(pGlyphs);
@ -1199,7 +1165,7 @@ int main(int argc, char* argv[])
}
// INTERACTIVE FORMS
if (true)
if (false)
{
ReadInteractiveFormsFonts(pGrFile, 1);
ReadInteractiveFormsFonts(pGrFile, 2);

View File

@ -19,10 +19,6 @@ core_linux {
QMAKE_CXXFLAGS += -Wno-narrowing
}
core_linux_clang {
QMAKE_CFLAGS += -Wno-incompatible-function-pointer-types
}
core_mac {
DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H
}

View File

@ -1,11 +0,0 @@
#include <codecvt>
#include "../../pro/Graphics.h"
int main(int argc, char *argv[])
{
Aggplus::CImage Cimg(std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(argv[1]));
Cimg.SaveFile(std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(argv[2]), 1);
return 0;
}

View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@ -0,0 +1,182 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QImage>
#include <QPixmap>
#include <QSpinBox>
#include <QComboBox>
#include <QStringList>
#include "../../pro/Graphics.h"
static constexpr double rectangle[4] = {
10.0, 10.0, 80.0, 80.0,
};
static const QStringList patterns = {
"cross",
"dashDnDiag",
"dashHorz",
"dashUpDiag",
"dashVert",
"diagBrick",
"diagCross",
"divot",
"dkDnDiag",
"dkHorz",
"dkUpDiag",
"dkVert",
"dnDiag",
"dotDmnd",
"dotGrid",
"horz",
"horzBrick",
"lgCheck",
"lgConfetti",
"lgGrid",
"ltDnDiag",
"ltHorz",
"ltUpDiag",
"ltVert",
"narHorz",
"narVert",
"openDmnd",
"pct10",
"pct20",
"pct25",
"pct30",
"pct40",
"pct5",
"pct50",
"pct60",
"pct70",
"pct75",
"pct80",
"pct90",
"plaid",
"shingle",
"smCheck",
"smConfetti",
"smGrid",
"solidDmnd",
"sphere",
"trellis",
"upDiag",
"vert",
"wave",
"wdDnDiag",
"wdUpDiag",
"weave",
"zigZag"
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->pushButton->SetColor(Qt::red);
ui->pushButton_2->SetColor(Qt::blue);
ui->comboBox->addItems(patterns);
connect(ui->pushButton, &CColorButton::ColorChanged, this, &MainWindow::Draw);
connect(ui->pushButton_2, &CColorButton::ColorChanged, this, &MainWindow::Draw);
connect(ui->spinBox, &QSpinBox::valueChanged, this, &MainWindow::Draw);
connect(ui->spinBox_2, &QSpinBox::valueChanged, this, &MainWindow::Draw);
connect(ui->comboBox, &QComboBox::currentTextChanged, this, &MainWindow::Draw);
connect(ui->radioButton, &QRadioButton::clicked, this, &MainWindow::Draw);
connect(ui->radioButton_2, &QRadioButton::clicked, this, &MainWindow::Draw);
m_oPathRectangle.StartFigure();
m_oPathRectangle.MoveTo(rectangle[0], rectangle[1]);
m_oPathRectangle.LineTo(rectangle[0] + rectangle[2], rectangle[1]);
m_oPathRectangle.LineTo(rectangle[0] + rectangle[2], rectangle[1] + rectangle[3]);
m_oPathRectangle.LineTo(rectangle[0], rectangle[1] + rectangle[3]);
m_oPathRectangle.LineTo(rectangle[0], rectangle[1]);
m_oPathRectangle.CloseFigure();
m_oPathEllisps.StartFigure();
m_oPathEllisps.AddEllipse(rectangle[0], rectangle[1], rectangle[2], rectangle[3]);
m_oPathEllisps.CloseFigure();
Draw();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::Draw()
{
NSGraphics::IGraphicsRenderer *renderer = NSGraphics::Create();
int width = ui->label->width(),
height = ui->label->height();
BYTE* data = new BYTE[4 * width * height];
CBgraFrame frame;
frame.put_Data(data);
frame.put_Width(width);
frame.put_Height(height);
frame.put_Stride(4 * width);
renderer->put_Width(100);
renderer->put_Height(100);
renderer->CreateFromBgraFrame(&frame);
renderer->SetSwapRGB(false);
renderer->put_BrushType(c_BrushTypeHatch1);
renderer->put_BrushTexturePath(ui->comboBox->currentText().toStdWString());
renderer->put_BrushColor1(ui->pushButton->GetColor().rgb());
renderer->put_BrushAlpha1(ui->spinBox->value());
renderer->put_BrushColor2(ui->pushButton_2->GetColor().rgb());
renderer->put_BrushAlpha2(ui->spinBox->value());
std::vector<Aggplus::PointD> points;
unsigned length;
bool is_rectangle = ui->radioButton->isChecked();
if (is_rectangle)
{
length = m_oPathRectangle.GetPointCount();
points = m_oPathRectangle.GetPoints(0, length);
}
else
{
length = m_oPathEllisps.GetPointCount();
points = m_oPathEllisps.GetPoints(0, length);
}
renderer->BeginCommand(c_nPathType);
renderer->PathCommandStart();
for (unsigned i = 0; i < length; i++)
{
if (is_rectangle ? m_oPathRectangle.IsCurvePoint(i) : m_oPathEllisps.IsCurvePoint(i))
{
renderer->PathCommandCurveTo(points[i].X, points[i].Y,
points[i + 1].X, points[i + 1].Y,
points[i + 2].X, points[i + 2].Y);
i += 2;
}
else if (is_rectangle ? m_oPathRectangle.IsMovePoint(i) : m_oPathEllisps.IsMovePoint(i))
renderer->PathCommandMoveTo(points[i].X, points[i].Y);
else if (is_rectangle ? m_oPathRectangle.IsLinePoint(i) : m_oPathEllisps.IsLinePoint(i))
renderer->PathCommandLineTo(points[i].X, points[i].Y);
}
renderer->PathCommandClose();
renderer->Fill();
renderer->EndCommand(c_nPathType);
renderer->PathCommandEnd();
auto img = QImage(data, width, height, QImage::Format_RGBA8888, [](void *data){
delete[] (BYTE*)data;
});
ui->label->setPixmap(QPixmap::fromImage(img));
RELEASEOBJECT(renderer);
}

View File

@ -0,0 +1,81 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QColor>
#include <QColorDialog>
#include <QPalette>
#include "../../GraphicsPath.h"
class CColorButton final : public QPushButton
{
Q_OBJECT
public:
CColorButton(QWidget *parent = nullptr) : QPushButton(parent)
{
connect(this, &QPushButton::clicked, this, &CColorButton::onClicked);
}
~CColorButton() {}
QColor GetColor() const
{
return m_oColor;
}
void SetColor(const QColor& color)
{
if (color == m_oColor)
return;
m_oColor = color;
setStyleSheet("QPushButton { background-color : " + m_oColor.name()
+ "; border: 1px solid black; padding 10px;}");
emit ColorChanged();
}
signals:
void ColorChanged();
public slots:
void onClicked()
{
QColorDialog color_dialog;
auto color = color_dialog.getColor();
if (color.isValid())
SetColor(color);
}
private:
QColor m_oColor;
};
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void Draw();
private:
Aggplus::CGraphicsPath m_oPathRectangle;
Aggplus::CGraphicsPath m_oPathEllisps;
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,253 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>368</width>
<height>538</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>30</x>
<y>190</y>
<width>300</width>
<height>300</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>321</width>
<height>151</height>
</rect>
</property>
<property name="title">
<string>Hatch brush parametrs</string>
</property>
<widget class="CColorButton" name="pushButton">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>31</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="CColorButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>110</x>
<y>40</y>
<width>31</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>First color:</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>110</x>
<y>20</y>
<width>81</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Second color:</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>110</x>
<y>70</y>
<width>81</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Second alpha:</string>
</property>
</widget>
<widget class="QSpinBox" name="spinBox">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>42</width>
<height>25</height>
</rect>
</property>
<property name="maximum">
<number>255</number>
</property>
<property name="value">
<number>255</number>
</property>
</widget>
<widget class="QSpinBox" name="spinBox_2">
<property name="geometry">
<rect>
<x>110</x>
<y>90</y>
<width>42</width>
<height>25</height>
</rect>
</property>
<property name="maximum">
<number>255</number>
</property>
<property name="value">
<number>255</number>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>200</x>
<y>20</y>
<width>81</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Type:</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>200</x>
<y>40</y>
<width>110</width>
<height>24</height>
</rect>
</property>
</widget>
<widget class="QGroupBox" name="groupBox_2">
<property name="geometry">
<rect>
<x>200</x>
<y>70</y>
<width>110</width>
<height>70</height>
</rect>
</property>
<property name="title">
<string>Path:</string>
</property>
<widget class="QRadioButton" name="radioButton">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Rectangle</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<widget class="QRadioButton" name="radioButton_2">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Circle</string>
</property>
</widget>
</widget>
<widget class="QLabel" name="label_7">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>First alpha:</string>
</property>
</widget>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>20</x>
<y>160</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Output:</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>368</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>CColorButton</class>
<extends>QPushButton</extends>
<header>mainwindow.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,20 @@
QT += core gui widgets
QMAKE_CXXFLAGS += /permissive-
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
PWD_ROOT_DIR = $$PWD
CORE_ROOT_DIR = $$PWD/../../../../../core
include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)

View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@ -0,0 +1,62 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QLabel>
#include <QSizePolicy>
#include <QDir>
#include "../../../../UnicodeConverter/UnicodeConverter.h"
#include "../../pro/Graphics.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
ui->label->setFixedWidth(310);
ui->comboBox->addItems(m_arExtensions);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
m_arFileNames = QFileDialog::getOpenFileNames(this,
"Select one or more images",
"",
"*.bmp *.gif *.jpg *.png *.ico "
"*.tif *.tga *.pcx *.wbmp *.jp2 "
"*.jpc *.pgx *.pnm *.ras *.jbg "
"*.mng *.ska *.raw *.psd *.pic");
if (!m_arFileNames.empty())
ui->label->setText("File:" + m_arFileNames[0]);
}
void MainWindow::on_pushButton_2_clicked()
{
auto save_dir = QFileDialog::getExistingDirectory(this,
"Open Directory",
"",
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
auto ext = ui->comboBox->currentText();
NSUnicodeConverter::CUnicodeConverter converter;
for (const auto& f : m_arFileNames)
{
ui->label->setText("File:" + f);
Aggplus::CImage img(converter.toUnicode(f.toStdString(), 1));
img.SaveFile(converter.toUnicode(QDir(save_dir).filePath("res." + ext).toStdString(), 1),
m_mapExtensionCodes.value(ext));
}
}

View File

@ -0,0 +1,75 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QString>
#include <QStringList>
#include <QMap>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
QStringList m_arFileNames;
QStringList m_arExtensions = {
"bmp",
"gif",
"jpg",
"png",
"ico",
"tif",
"tga",
"pcx",
"wbmp",
"jp2",
"jpc",
"pgx",
"pnm",
"ras",
"mng",
"ska",
"raw",
"psd",
"pic",
};
QMap<QString, int> m_mapExtensionCodes = {
{"bmp", 1},
{"gif", 2},
{"jpg", 3},
{"png", 4},
{"ico", 5},
{"tif", 6},
{"tga", 7},
{"pcx", 8},
{"wbmp", 9},
{"jp2", 11},
{"jpc", 12},
{"pgx", 13},
{"pnm", 14},
{"ras", 15},
{"mng", 17},
{"ska", 18},
{"raw", 19},
{"psd", 20},
{"pic", 25},
};
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>385</width>
<height>196</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>40</x>
<y>20</y>
<width>121</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string>Choose img file</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>40</x>
<y>50</y>
<width>310</width>
<height>91</height>
</rect>
</property>
<property name="text">
<string>File:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>270</x>
<y>20</y>
<width>80</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string>Convert</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>180</x>
<y>20</y>
<width>72</width>
<height>24</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>385</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,13 +1,8 @@
#CONFIG += c++11 cmdline
CONFIG += c++11
#SOURCES += \
QT -= core
QMAKE_CXXFLAGS += /permissive-
QT -= gui
TARGET = test
CONFIG += console
TEMPLATE = app
QT += core gui widgets
CORE_ROOT_DIR = $$PWD/../../../..
PWD_ROOT_DIR = $$PWD
@ -21,6 +16,13 @@ GRAPHICS_AGG_PATH = $$PWD/../../../agg-2.4
INCLUDEPATH += \
$$GRAPHICS_AGG_PATH/include
SOURCES += main.cpp
SOURCES += main.cpp \
mainwindow.cpp
DESTDIR = $$PWD_ROOT_DIR/build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX
FORMS += \
mainwindow.ui
HEADERS += \
mainwindow.h

View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@ -0,0 +1,76 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QLabel>
#include <QSizePolicy>
#include <QDir>
#include "../../../../UnicodeConverter/UnicodeConverter.h"
#include "../../pro/Graphics.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
ui->label->setFixedWidth(160);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
m_arFileNames = QFileDialog::getOpenFileNames(this,
"Select one or more metafiles to convert",
"",
"*.emf *.wmf *.svm *.svg");
if (!m_arFileNames.empty())
ui->label->setText("File:" + m_arFileNames[0]);
}
void MainWindow::on_pushButton_2_clicked()
{
auto save_dir = QFileDialog::getExistingDirectory(this,
"Open Directory",
"",
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
NSUnicodeConverter::CUnicodeConverter converter;
for (const auto& f : m_arFileNames)
{
ui->label->setText("File:" + f);
NSFonts::IApplicationFonts* app_fonts = NSFonts::NSApplication::Create();
app_fonts->Initialize();
MetaFile::IMetaFile* meta_file = MetaFile::Create(app_fonts);
if (!meta_file->LoadFromFile(converter.toUnicode(f.toStdString(), 1).c_str()))
return;
double x, y, w, h;
meta_file->GetBounds(&x, &y, &w, &h);
if (ui->radioButton->isChecked())
meta_file->ConvertToRaster(converter.toUnicode(QDir(save_dir).filePath("res.bmp").toStdString(), 1).c_str(), 1,
static_cast<int>(w) + 1, static_cast<int>(h) + 1);
else if (ui->radioButton_2->isChecked())
meta_file->ConvertToXml(converter.toUnicode(QDir(save_dir).filePath("res.xml").toStdString(), 1).c_str());
else if (ui->radioButton_3->isChecked())
meta_file->ConvertToRaster(converter.toUnicode(QDir(save_dir).filePath("res.bmp").toStdString(), 1).c_str(), 1,
static_cast<int>(w) + 1, static_cast<int>(h) + 1,
converter.toUnicode(QDir(save_dir).filePath("res.xml").toStdString(), 1).c_str());
else if (ui->radioButton_4->isChecked())
meta_file->ConvertToSvg(static_cast<int>(w) + 1, static_cast<int>(h) + 1);
else if (ui->radioButton_5->isChecked())
meta_file->ConvertToEmf(converter.toUnicode(QDir(save_dir).filePath("res.emf").toStdString(), 1).c_str());
RELEASEOBJECT(app_fonts);
RELEASEOBJECT(meta_file);
}
}

View File

@ -0,0 +1,32 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QString>
#include <QStringList>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
QStringList m_arFileNames;
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>540</width>
<height>211</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>50</x>
<y>60</y>
<width>161</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string>Choose Metafile</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>250</x>
<y>0</y>
<width>151</width>
<height>131</height>
</rect>
</property>
<property name="title">
<string>Choose to convert</string>
</property>
<widget class="QRadioButton" name="radioButton">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Raster(.bmp)</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton_2">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Xml</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton_3">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>131</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Raster(.bmp) + Xml</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton_4">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Svg</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton_5">
<property name="geometry">
<rect>
<x>10</x>
<y>110</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Emf</string>
</property>
</widget>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>450</x>
<y>60</y>
<width>80</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string>Convert</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>60</x>
<y>90</y>
<width>151</width>
<height>71</height>
</rect>
</property>
<property name="text">
<string>File: </string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="openExternalLinks">
<bool>false</bool>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>540</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,23 @@
CONFIG += c++11
QMAKE_CXXFLAGS += /permissive-
QT += core gui widgets
SOURCES += \
main.cpp\
mainwindow.cpp
FORMS += \
mainwindow.ui
HEADERS += \
mainwindow.h
PWD_ROOT_DIR = $$PWD
CORE_ROOT_DIR = $$PWD/../../../../../core
include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)

View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@ -0,0 +1,97 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iterator>
#include <QImage>
#include <QPixmap>
#include <QString>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->pushButton->SetColor(Qt::black);
m_oAppFonts = NSFonts::NSApplication::Create();
m_oAppFonts->Initialize();
m_oFontManager = m_oAppFonts->GenerateFontManager();
NSFonts::IFontsCache* fonts_cache = NSFonts::NSFontCache::Create();
fonts_cache->SetStreams(m_oAppFonts->GetStreams());
m_oFontManager->SetOwnerCache(fonts_cache);
for (auto it = m_oAppFonts->GetList()->GetFonts()->cbegin(); it != m_oAppFonts->GetList()->GetFonts()->cend(); it++)
ui->comboBox->addItem(QString::fromWCharArray((*it)->m_wsFontName.c_str()));
connect(ui->textEdit, &QTextEdit::textChanged, this, &MainWindow::Draw);
connect(ui->spinBox, &QSpinBox::valueChanged, this, &MainWindow::Draw);
connect(ui->comboBox, &QComboBox::currentTextChanged, this, &MainWindow::Draw);
connect(ui->checkBox, &QCheckBox::stateChanged, this, &MainWindow::Draw);
connect(ui->checkBox_2, &QCheckBox::stateChanged, this, &MainWindow::Draw);
connect(ui->pushButton, &CColorButton::ColorChanged, this, &MainWindow::Draw);
}
MainWindow::~MainWindow()
{
RELEASEOBJECT(m_oAppFonts);
RELEASEOBJECT(m_oFontManager);
delete ui;
}
void MainWindow::Draw()
{
NSGraphics::IGraphicsRenderer* renderer = NSGraphics::Create();
renderer->SetFontManager(m_oFontManager);
int width = ui->label->width(),
height = ui->label->height();
BYTE* data = new BYTE[4 * width * height];
CBgraFrame frame;
frame.put_Data(data);
frame.put_Width(width);
frame.put_Height(height);
frame.put_Stride(4 * width);
renderer->put_Width(100);
renderer->put_Height(100);
renderer->CreateFromBgraFrame(&frame);
renderer->SetSwapRGB(false);
renderer->put_FontName(ui->comboBox->currentText().toStdWString());
renderer->put_FontSize(ui->spinBox->value());
long font_style = 0;
if (ui->checkBox->isChecked())
font_style |= 0x01;
if (ui->checkBox_2->isChecked())
font_style |= 0x02;
renderer->put_FontStyle(font_style);
renderer->put_BrushColor1(ui->pushButton->GetColor().rgb());
auto lines = ui->textEdit->toPlainText().split('\n');
double x = 1.0;
double y = (ui->spinBox->value() * 25.4 / 96.0) + 3.0;
double scale_y = y;
renderer->BeginCommand(c_nTextGraphicType);
for (auto it = lines.cbegin(); it != lines.cend(); it++)
{
renderer->CommandDrawText((*it).toStdWString(), x, y, 0.0, 0.0);
y += scale_y;
}
renderer->EndCommand(c_nTextGraphicType);
QImage img = QImage(data, width, height, QImage::Format_RGBA8888, [](void *data){
delete[] (BYTE*)data;
});
ui->label->setPixmap(QPixmap::fromImage(img));
RELEASEOBJECT(renderer);
}

View File

@ -0,0 +1,80 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "../../pro/Graphics.h"
#include <QMainWindow>
#include <QPushButton>
#include <QColor>
#include <QColorDialog>
#include <QPalette>
class CColorButton final : public QPushButton
{
Q_OBJECT
public:
CColorButton(QWidget *parent = nullptr) : QPushButton(parent)
{
connect(this, &QPushButton::clicked, this, &CColorButton::onClicked);
}
~CColorButton() {}
QColor GetColor() const
{
return m_oColor;
}
void SetColor(const QColor& color)
{
if (color == m_oColor)
return;
m_oColor = color;
setStyleSheet("QPushButton { background-color : " + m_oColor.name()
+ "; border: 1px solid black; padding 10px;}");
emit ColorChanged();
}
signals:
void ColorChanged();
public slots:
void onClicked()
{
QColorDialog color_dialog;
auto color = color_dialog.getColor();
if (color.isValid())
SetColor(color);
}
private:
QColor m_oColor;
};
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void Draw();
private:
Ui::MainWindow *ui;
NSFonts::IApplicationFonts* m_oAppFonts;
NSFonts::IFontManager* m_oFontManager;
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,214 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>471</width>
<height>390</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>130</y>
<width>450</width>
<height>200</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QTextEdit" name="textEdit">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>180</width>
<height>70</height>
</rect>
</property>
<property name="placeholderText">
<string>Hello</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>0</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Text input:</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>200</x>
<y>0</y>
<width>261</width>
<height>91</height>
</rect>
</property>
<property name="title">
<string>Brush</string>
</property>
<widget class="QSpinBox" name="spinBox">
<property name="geometry">
<rect>
<x>140</x>
<y>40</y>
<width>42</width>
<height>25</height>
</rect>
</property>
<property name="value">
<number>30</number>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>140</x>
<y>20</y>
<width>49</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Font size:</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>51</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Bold</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox_2">
<property name="geometry">
<rect>
<x>60</x>
<y>70</y>
<width>51</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Italic</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>200</x>
<y>20</y>
<width>41</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Color:</string>
</property>
</widget>
<widget class="CColorButton" name="pushButton">
<property name="geometry">
<rect>
<x>200</x>
<y>40</y>
<width>31</width>
<height>24</height>
</rect>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>31</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Font:</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>121</width>
<height>24</height>
</rect>
</property>
<property name="duplicatesEnabled">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>10</x>
<y>100</y>
<width>71</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Text output:</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>471</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>CColorButton</class>
<extends>QPushButton</extends>
<header>mainwindow.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,20 @@
QT += core gui widgets
QMAKE_CXXFLAGS += /permissive-
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
PWD_ROOT_DIR = $$PWD
CORE_ROOT_DIR = $$PWD/../../../../../core
include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)

View File

@ -34,7 +34,6 @@
#include <string>
#include <cfloat>
#include <cmath>
#include "../../../common/StringExt.h"
#ifndef BYTE

View File

@ -645,9 +645,6 @@ namespace MetaFile
//TODO::реализовать при встрече
}
if (BrushDataTransform & unBrushDataFlags)
m_oStream.Skip(24);
if (BrushDataPresetColors & unBrushDataFlags)
{
unsigned int unPositionCount;

View File

@ -47,11 +47,18 @@ namespace MetaFile
return new CMetaFile(pAppFonts);
}
/**
* @brief CMetaFile Constructor
* @param pAppFonts
*
* Create a font manager accordingly Applications Fonts for the
* appropriate metafile.
*/
CMetaFile::CMetaFile(NSFonts::IApplicationFonts *pAppFonts) : MetaFile::IMetaFile(pAppFonts)
{
m_pFontManager = NULL;
m_pAppFonts = pAppFonts;
// Создаем менеджер шрифтов с собственным кэшем
if (pAppFonts)
{
m_pFontManager = pAppFonts->GenerateFontManager();
@ -60,28 +67,35 @@ namespace MetaFile
m_pFontManager->SetOwnerCache(pMeasurerCache);
}
#ifdef METAFILE_SUPPORT_WMF_EMF
m_oWmfFile.SetFontManager(m_pFontManager);
m_oEmfFile.SetFontManager(m_pFontManager);
#endif
#ifdef METAFILE_SUPPORT_SVM
m_oSvmFile.SetFontManager(m_pFontManager);
#endif
m_lType = 0;
}
/**
* @brief CMetaFile::get_FontManager
* @return Pointer of current Font Manager
*/
NSFonts::IFontManager* CMetaFile::get_FontManager()
{
return m_pFontManager;
}
/**
* @brief CMetaFile Destructor
*
* Close metafile and release memory, allocated for Font Manager
*/
CMetaFile::~CMetaFile()
{
Close();
RELEASEINTERFACE(m_pFontManager);
}
/**
* @brief CMetaFile::ConvertToSvg
* @param unWidth - width of picture from metafile (0 - default)
* @param unHeight - height of picture from metafile (0 - default)
* @return string containing svg content
*/
std::wstring CMetaFile::ConvertToSvg(unsigned int unWidth, unsigned int unHeight)
{
@ -102,7 +116,16 @@ namespace MetaFile
return L"";
}
/**
* @brief Methods for conversation in test examples
*/
#ifdef METAFILE_SUPPORT_WMF_EMF
/**
* @brief CMetaFile::ConvertToXml
* @param wsFilePath - path to the file being saving (must be .xml)
*
* Convert and save metafile data to .xml
*/
void CMetaFile::ConvertToXml(const wchar_t *wsFilePath)
{
if (NULL == wsFilePath)
@ -112,129 +135,17 @@ namespace MetaFile
m_oEmfFile.PlayMetaFile();
}
void CMetaFile::ConvertToXmlAndRaster(const wchar_t *wsXmlFilePath, const wchar_t *wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight)
{
if (NULL == wsXmlFilePath || NULL == wsOutFilePath)
return;
m_oEmfFile.SetOutputDevice(NULL, wsXmlFilePath);
NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create();
NSFonts::IFontManager* pFontManager = m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
pFontCache->SetStreams(m_pAppFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache);
pGrRenderer->SetFontManager(pFontManager);
if (-1 == nHeight)
{
double dX, dY, dW, dH;
GetBounds(&dX, &dY, &dW, &dH);
if (dW < 0)
dW = -dW;
if (dH < 0)
dH = -dH;
if (nWidth < 0) nWidth = (int)(dW * 96 / 25.4);
nHeight = (int)((double)nWidth * dH / dW);
}
double dWidth = 25.4 * nWidth / 96;
double dHeight = 25.4 * nHeight / 96;
BYTE* pBgraData = new(std::nothrow) BYTE[nWidth * nHeight * 4];
if (!pBgraData)
return;
unsigned int alfa = 0xffffff;
//дефолтный тон должен быть прозрачным, а не белым
//memset(pBgraData, 0xff, nWidth * nHeight * 4);
for (int i = 0; i < nWidth * nHeight; i++)
{
((unsigned int*)pBgraData)[i] = alfa;
}
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride(-4 * nWidth);
pGrRenderer->CreateFromBgraFrame(&oFrame);
pGrRenderer->SetSwapRGB(false);
pGrRenderer->put_Width(dWidth);
pGrRenderer->put_Height(dHeight);
DrawOnRenderer(wsXmlFilePath, pGrRenderer, 0, 0, dWidth, dHeight);
oFrame.SaveFile(wsOutFilePath, unFileType);
RELEASEINTERFACE(pFontManager);
RELEASEINTERFACE(pGrRenderer);
}
bool CMetaFile::DrawOnRenderer(const wchar_t *wsXmlFilePath, IRenderer *pRenderer, double dX, double dY, double dWidth, double dHeight)
{
if (NULL == wsXmlFilePath || NULL == pRenderer)
return false;
pRenderer->BeginCommand(c_nImageType);
switch (m_lType)
{
#ifdef METAFILE_SUPPORT_WMF_EMF
case c_lMetaWmf:
{
CMetaFileRenderer oWmfOut(m_oWmfFile.GetWmfParser(), pRenderer, dX, dY, dWidth, dHeight);
m_oWmfFile.SetOutputDevice((IOutputDevice*)&oWmfOut);
m_oWmfFile.PlayMetaFile();
break;
}
case c_lMetaEmf:
{
CMetaFileRenderer oEmfOut(m_oEmfFile.GetEmfParser(), pRenderer, dX, dY, dWidth, dHeight);
m_oEmfFile.SetOutputDevice((IOutputDevice*)&oEmfOut, wsXmlFilePath);
m_oEmfFile.PlayMetaFile();
break;
}
#endif
#ifdef METAFILE_SUPPORT_SVM
case c_lMetaSvm:
{
CMetaFileRenderer oSvmOut(&m_oSvmFile, pRenderer, dX, dY, dWidth, dHeight);
m_oSvmFile.SetOutputDevice((IOutputDevice*)&oSvmOut);
m_oSvmFile.PlayMetaFile();
break;
}
#endif
#ifdef METAFILE_SUPPORT_SVG
case c_lMetaSvg:
{
m_oSvgFile.Draw(pRenderer, dX, dY, dWidth, dHeight);
break;
}
#endif
default:
break;
}
pRenderer->EndCommand(c_nImageType);
return true;
}
/**
* @brief CMetaFile::LoadFromXmlFile
* @param wsFilePath - path to the source file (must be .xml)
* @return if correct reading - return true, elde - false
*
* Load meta file content from source .xml file.
* Remake Font Manager for metafile
*/
bool CMetaFile::LoadFromXmlFile(const wchar_t *wsFilePath)
{
RELEASEINTERFACE(m_pFontManager);
if (m_pAppFonts)
{
m_pFontManager = m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
}
m_pFontManager->ClearOwnerCache();
m_oWmfFile.SetFontManager(m_pFontManager);
m_oEmfFile.SetFontManager(m_pFontManager);
@ -264,6 +175,10 @@ namespace MetaFile
return false;
}
/**
* @brief CMetaFile::ConvertToEmf
* @param wsFilePath - path to the file being saving (must be .emf)
*/
void CMetaFile::ConvertToEmf(const wchar_t *wsFilePath)
{
if (m_lType != c_lMetaEmf || m_oEmfFile.GetEmfParser()->GetType() != EmfParserType::EmfxParser)
@ -276,21 +191,18 @@ namespace MetaFile
}
#endif
/**
* @brief CMetaFile::LoadFromFile
* @param wsFilePath - path to source file
* @return if correct reading - return true, elde - false
*
* Load from source file
* Remake Font Manager for metafile, for each picture
* Check file extansion (wmf, emf, svm, svg)
*/
bool CMetaFile::LoadFromFile(const wchar_t *wsFilePath)
{
// TODO: Сейчас при загрузке каждой новой картинки мы пересоздаем
// FontManager, потому что сейчас в нем кэш без ограничения.
//------------------------------------------------------
RELEASEINTERFACE(m_pFontManager);
if (m_pAppFonts)
{
m_pFontManager = m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
}
m_pFontManager->ClearOwnerCache();
#ifdef METAFILE_SUPPORT_WMF_EMF
m_oWmfFile.SetFontManager(m_pFontManager);
@ -305,10 +217,7 @@ namespace MetaFile
m_oSvgFile.SetFontManager(m_pFontManager);
#endif
//------------------------------------------------------
#ifdef METAFILE_SUPPORT_WMF_EMF
// Сначала пытаемся открыть файл как Wmf
if (m_oWmfFile.OpenFromWmfFile(wsFilePath) == true)
{
m_oWmfFile.Scan();
@ -320,7 +229,7 @@ namespace MetaFile
}
m_oWmfFile.Close();
}
// Это не Wmf
if (m_oEmfFile.OpenFromEmfFile(wsFilePath) == true)
{
m_oEmfFile.Scan();
@ -333,7 +242,7 @@ namespace MetaFile
m_oEmfFile.Close();
}
#endif
// Это не Emf
#ifdef METAFILE_SUPPORT_SVM
if (m_oSvmFile.OpenFromFile(wsFilePath) == true)
{
@ -348,37 +257,47 @@ namespace MetaFile
m_oSvmFile.Close();
}
#endif
// Это не svm
#ifdef METAFILE_SUPPORT_SVG
if (m_oSvgFile.OpenFromFile(wsFilePath) == true)
{
m_lType = c_lMetaSvg;
return true;
}
#endif
return false;
}
/**
* @brief CMetaFile::LoadFromBuffer
* @param pBuffer - pointer of buffer whith metacontent
* for example, the buffer obtained after reading the file
* @code
* NSFile::CFileBinary file;
* file.OpenFile(L"file_name");
* DWORD file_size = file.GetFileSize();
* BYTE* data = new BYTE[file_size];
* file.ReadFile(data, file_size);
* @endcode
* @param unSize - buffer size (size of file or readed size)
* @code
* DWORD readed_size;
* file.ReadFile(data, file_size, readed_size);
* @endcode
* @return if correct format load for extansion - return true,
* else - false
*
* Load metafile content from buffer
* Remake Font Manager for metafile, for each picture
* Check type of content in buffer, appropriate extension (wmf, emf, svm, svg)
*/
bool CMetaFile::LoadFromBuffer(BYTE *pBuffer, unsigned int unSize)
{
if (NULL == pBuffer || 0 == unSize)
return false;
// TODO: Сейчас при загрузке каждой новой картинки мы пересоздаем
// FontManager, потому что сейчас в нем кэш без ограничения.
//------------------------------------------------------
RELEASEINTERFACE(m_pFontManager);
if (m_pAppFonts)
{
m_pFontManager = m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
}
m_pFontManager->ClearOwnerCache();
#ifdef METAFILE_SUPPORT_WMF_EMF
m_oWmfFile.SetFontManager(m_pFontManager);
@ -393,10 +312,7 @@ namespace MetaFile
m_oSvgFile.SetFontManager(m_pFontManager);
#endif
//------------------------------------------------------
#ifdef METAFILE_SUPPORT_WMF_EMF
// Сначала пытаемся открыть файл как Wmf
if (m_oWmfFile.ReadFromBuffer(pBuffer, unSize) == true)
{
m_oWmfFile.Scan();
@ -408,7 +324,7 @@ namespace MetaFile
}
m_oWmfFile.Close();
}
// Это не Wmf
if (m_oEmfFile.ReadFromBuffer(pBuffer, unSize) == true)
{
m_oEmfFile.Scan();
@ -421,7 +337,7 @@ namespace MetaFile
m_oEmfFile.Close();
}
#endif
// Это не Emf
#ifdef METAFILE_SUPPORT_SVM
if (m_oSvmFile.ReadFromBuffer(pBuffer, unSize) == true)
{
@ -436,7 +352,7 @@ namespace MetaFile
m_oSvmFile.Close();
}
#endif
// Это не svm
#ifdef METAFILE_SUPPORT_SVG
if (m_oSvgFile.ReadFromBuffer(pBuffer, unSize) == true)
{
@ -448,19 +364,18 @@ namespace MetaFile
return false;
}
/**
* @brief CMetaFile::LoadFromString
* @param data - source string, containing svg metadata (.svg extension type)
* @return if correct read svg content - return true, else - false
*
* Load .svg content from wide string
* Remake Font Manager for metafile, for each picture
*/
bool CMetaFile::LoadFromString(const std::wstring& data)
{
m_pFontManager->ClearOwnerCache();
#ifdef METAFILE_SUPPORT_SVG
RELEASEINTERFACE(m_pFontManager);
if (m_pAppFonts)
{
m_pFontManager = m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
}
m_oSvgFile.SetFontManager(m_pFontManager);
if (m_oSvgFile.ReadFromWString(data) == true)
@ -472,6 +387,10 @@ namespace MetaFile
return false;
}
/**
* @brief CMetaFile::SetTempDirectory
* @param dir - path to working directory
*/
void CMetaFile::SetTempDirectory(const std::wstring& dir)
{
#ifdef METAFILE_SUPPORT_SVG
@ -479,7 +398,23 @@ namespace MetaFile
#endif
}
bool CMetaFile::DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight)
/**
* @brief CMetaFile::DrawOnRenderer
* @param pRenderer - class instance of CGraphicsRenderer, which will render
* meta content
* @param dX - start coordinate for X axis
* @param dY - start coordinate for Y axis
* @param dWidth - width of picture from metafile
* @param dHeight - height of picture from metafile
* @param wsXmlFilePath - path to the file being saveing as xml commands from
* metafile (default - nullptr)
* @return if none render - return false, else - true
*
* Check type of metacontent
* Draw the meta file picture on renderer
*/
bool CMetaFile::DrawOnRenderer(IRenderer* pRenderer, double dX, double dY,
double dWidth, double dHeight, const wchar_t* wsXmlFilePath)
{
if (NULL == pRenderer)
return false;
@ -499,7 +434,10 @@ namespace MetaFile
case c_lMetaEmf:
{
CMetaFileRenderer oEmfOut(m_oEmfFile.GetEmfParser(), pRenderer, dX, dY, dWidth, dHeight);
m_oEmfFile.SetOutputDevice((IOutputDevice*)&oEmfOut);
if (wsXmlFilePath)
m_oEmfFile.SetOutputDevice((IOutputDevice*)&oEmfOut, wsXmlFilePath);
else
m_oEmfFile.SetOutputDevice((IOutputDevice*)&oEmfOut);
m_oEmfFile.PlayMetaFile();
break;
}
@ -528,6 +466,11 @@ namespace MetaFile
return true;
}
/**
* @brief CMetaFile::Close
*
* Close each type file (type = 0)
*/
void CMetaFile::Close()
{
#ifdef METAFILE_SUPPORT_WMF_EMF
@ -542,11 +485,27 @@ namespace MetaFile
m_lType = 0;
}
/**
* @brief CMetaFile::GetType
* @return type of metafile
* @enum
* c_lMetaWmf = 0x01;
* c_lMetaEmf = 0x02;
* c_lMetaSvg = 0x04;
* c_lMetaSvm = 0x05;
*/
int CMetaFile::GetType()
{
return m_lType;
}
/**
* @brief CMetaFile::GetBounds
* @param pdX - pointer to saving X coordinate of bounds
* @param pdY - pointer to saving Y coordinate of bounds
* @param pdW - pointer to saving Width of bounds
* @param pdH - pointer to saving height of bounds
*/
void CMetaFile::GetBounds(double* pdX, double* pdY, double* pdW, double* pdH)
{
switch (m_lType)
@ -609,11 +568,31 @@ namespace MetaFile
if (*pdH < 0) *pdH = -*pdH;
}
void CMetaFile::ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight)
/**
* @brief CMetaFile::ConvertToRaster
* @param wsOutFilePath - path to the file being saving (must be raster graphics
* like .bmp, .png, etc.)
* @param unFileType - type of raster file, see ENUM_CXIMAGE_FORMATS
* for example .bmp = 1, .png = 4
* @param unWidth - width of picture from metafile
* @param unHeight - height of picture from metafile (default -1)
* @param wsXmlOutFile(optional) - path to the file being saving metafile
* commands to .xml (default nullptr)
*
* Create Graphics Renderer and Font Manager
* Draw metafile content on created renderer and save in raster graphics file
*/
void CMetaFile::ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight, const wchar_t* wsXmlOutFile)
{
if (nWidth == 0 || nHeight == 0)
return;
if (NULL == wsOutFilePath)
return;
if (wsXmlOutFile != NULL)
m_oEmfFile.SetOutputDevice(NULL, wsXmlOutFile);
NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create();
NSFonts::IFontManager* pFontManager = m_pAppFonts->GenerateFontManager();
@ -637,8 +616,8 @@ namespace MetaFile
nHeight = (int)((double)nWidth * dH / dW);
}
double dWidth = 25.4 * nWidth / 96;
double dHeight = 25.4 * nHeight / 96;
double dWidth = 25.4 * nWidth / 96; // Get the width and height from pixels to mm
double dHeight = 25.4 * nHeight / 96; // 96 - standart DPI for inch
BYTE* pBgraData = (BYTE*)malloc(nWidth * nHeight * 4);
if (!pBgraData)
@ -658,12 +637,11 @@ namespace MetaFile
return;
unsigned int alfa = 0xffffff;
//дефолтный тон должен быть прозрачным, а не белым
//memset(pBgraData, 0xff, nWidth * nHeight * 4);
for (int i = 0; i < nWidth * nHeight; i++)
{
((unsigned int*)pBgraData)[i] = alfa;
((unsigned int*)pBgraData)[i] = alfa; // Set default tone (must be transparent and not white)
}
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
@ -675,10 +653,11 @@ namespace MetaFile
pGrRenderer->put_Width(dWidth);
pGrRenderer->put_Height(dHeight);
DrawOnRenderer(pGrRenderer, 0, 0, dWidth, dHeight);
DrawOnRenderer(pGrRenderer, 0, 0, dWidth, dHeight, wsXmlOutFile);
oFrame.SaveFile(wsOutFilePath, unFileType);
oFrame.put_Data(NULL);
RELEASEINTERFACE(pFontManager);
RELEASEINTERFACE(pGrRenderer);

View File

@ -56,36 +56,39 @@ typedef CSVGTransformer CSvgFile;
namespace MetaFile
{
/**
* @class CMetaFile
*
* The interface provides various options for loading a metafile and saving it
* in another format.
*/
class CMetaFile : public IMetaFile
{
public:
CMetaFile(NSFonts::IApplicationFonts *pAppFonts);
virtual ~CMetaFile();
void Close();
void SetTempDirectory(const std::wstring& dir);
bool LoadFromFile(const wchar_t* wsFilePath);
bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize);
bool LoadFromString(const std::wstring& data);
bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight);
void Close();
void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH);
int GetType();
void ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1);
void ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType,
int nWidth, int nHeight = -1, const wchar_t* wsXmlOutFile = NULL);
std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0);
bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY,
double dWidth, double dHeight, const wchar_t* wsXmlFilePath = NULL);
int GetType();
void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH);
NSFonts::IFontManager* get_FontManager();
//конвертация в Svg
std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0);
void SetTempDirectory(const std::wstring& dir);
//Для тестов
#ifdef METAFILE_SUPPORT_WMF_EMF
// For tests
void ConvertToXml(const wchar_t *wsFilePath);
void ConvertToXmlAndRaster(const wchar_t *wsXmlFilePath, const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1);
bool LoadFromXmlFile(const wchar_t* wsFilePath);
bool DrawOnRenderer(const wchar_t *wsXmlFilePath, IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight);
void ConvertToEmf(const wchar_t* wsFilePath);
#endif
private:

View File

@ -19,7 +19,6 @@ public:
};
int ConvertWidthToHWP(const std::wstring& wsValue);
int ConvertHexToInt(const std::string& wsValue, const int& _default = 0x00000000);
}
#endif // XMLNODEH_H

View File

@ -17,7 +17,20 @@ bool CXMLNode::GetAttributeBool(const std::wstring& wsName)
int CXMLNode::GetAttributeColor(const std::wstring& wsName, const int& _default)
{
return ConvertHexToInt(XmlUtils::CXmlNode::GetAttributeA(wsName), _default);
std::wstring sColor = XmlUtils::CXmlNode::GetAttribute(wsName);
if (L"none" != sColor)
{
if (L'#' == sColor.front())
sColor.erase(0, 1);
if (sColor.length() < 6)
return _default;
return std::stoi(sColor.substr(0, 6), nullptr, 16);
}
return _default;
}
CXMLNode CXMLNode::GetChild(const std::wstring& wsName)
@ -85,36 +98,4 @@ int ConvertWidthToHWP(const std::wstring& wsValue)
return 0;
}
int ConvertHexToInt(const std::string& wsValue, const int& _default)
{
if (wsValue.empty() || "none" == wsValue)
return _default;
std::string::const_iterator itStart = wsValue.cbegin();
if ('#' == *itStart)
++itStart;
if (wsValue.cend() - itStart < 6)
return _default;
itStart = wsValue.cend() - 6;
int nResult = 0;
while (itStart != wsValue.cend())
{
if ('0' <= *itStart && *itStart <= '9')
nResult = (nResult << 4) | (*itStart++ - '0');
else if ('A' <= *itStart && *itStart <= 'F')
nResult = (nResult << 4) | (*itStart++ - 'A' + 10);
else if ('a' <= *itStart && *itStart <= 'f')
nResult = (nResult << 4) | (*itStart++ - 'a' + 10);
else
return _default;
}
return nResult;
}
}

View File

@ -62,7 +62,12 @@ EColorFillPattern GetColorFillPattern(int nPattern)
void TBorder::ReadFromNode(CXMLNode& oNode)
{
m_eStyle = GetLineStyle2(oNode.GetAttribute(L"type"));
m_nColor = oNode.GetAttributeColor(L"color");
HWP_STRING sColor = std::regex_replace(oNode.GetAttribute(L"color"), std::wregex(L"^#([0-9A-Fa-f]+)$"), L"$1");
if (L"none" != sColor)
m_nColor = std::stoi(sColor, 0, 16);
m_chWidth = (HWP_BYTE)ConvertWidthToHWP(oNode.GetAttribute(L"width"));
}
@ -194,7 +199,7 @@ void CFill::ReadGradation(CXMLNode& oNode)
m_arColors.resize(arChilds.size());
for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex)
m_arColors[unIndex] = ConvertHexToInt(arChilds[unIndex].GetTextA());
m_arColors[unIndex] = std::stoi(std::regex_replace(arChilds[unIndex].GetText(), std::wregex(L"\\D"), L""), 0, 16);
}
void CFill::ReadImgBrush(CXMLNode& oNode)

View File

@ -48,16 +48,8 @@ CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, int nTagNum, int nLeve
CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion)
: CHWPRecord(EHWPTag::HWPTAG_BULLET, 0, 0), m_pParent(&oDocInfo)
{
std::wstring wsAttributeValue = oNode.GetAttribute(L"char");
if (!wsAttributeValue.empty())
m_chBulletChar = wsAttributeValue.at(0);
wsAttributeValue = oNode.GetAttribute(L"checkedChar");
if (!wsAttributeValue.empty())
m_chCheckBulletChar = wsAttributeValue.at(0);
m_chBulletChar = oNode.GetAttribute(L"char").at(0);
m_chCheckBulletChar = oNode.GetAttribute(L"checkedChar").at(0);
m_nBulletImage = oNode.GetAttributeInt(L"useImage");
for (CXMLNode& oChild : oNode.GetChilds())

View File

@ -619,7 +619,6 @@ namespace PPT
WriteSlides();
WriteNotes();
m_pShapeWriter->SetRelsGenerator(NULL);
}
// todo reforming and refactoring!
@ -1545,8 +1544,6 @@ namespace PPT
oRels.StartSlide(nLayout, pSlide->m_lNotesID);
}
m_pShapeWriter->SetRelsGenerator(&oRels);
oWriter.WriteString(std::wstring(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"));
oWriter.WriteString(std::wstring(L"<p:sld \
@ -1640,12 +1637,10 @@ xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\""));
{
CStringWriter oWriter;
CRelsGenerator oRels(&m_oManager);
CSlide* pNotes = m_pDocument->m_arNotes[nIndexNotes];
oRels.StartNotes(pNotes->m_lSlideID, m_pDocument->m_pNotesMaster != NULL);
m_pShapeWriter->SetRelsGenerator(&oRels);
oWriter.WriteString(std::wstring(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"));
oWriter.WriteString(std::wstring(L"<p:notes xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\""));

View File

@ -780,5 +780,20 @@ bool isColumn(const std::wstring& columnName, _UINT32 listIndex, _UINT16& indexC
}
return false;
}
unsigned int getColumnsCount(_UINT32 listIndex)
{
auto arrColumn = XLS::GlobalWorkbookInfo::mapTableColumnNames_static.find(listIndex);
if(arrColumn != XLS::GlobalWorkbookInfo::mapTableColumnNames_static.end())
{
auto counter = 0;
for(auto i:arrColumn->second)
{
if(!i.empty())
counter++;
}
return counter;
}
return 0;
}
} //namespace XMLSTUFF

View File

@ -87,13 +87,15 @@ namespace STR
};
namespace XMLSTUFF
{
{;
const std::wstring name2sheet_name(std::wstring name, const std::wstring prefix);
const std::wstring xti_indexes2sheet_name(const short tabFirst, const short tabLast, std::vector<std::wstring>& names, const std::wstring prefix = L"");
unsigned short sheetsnames2ixti(std::wstring name);
unsigned int definenames2index(std::wstring name);
bool isTableFmla(const std::wstring& tableName, _UINT32& listIndex);
bool isColumn(const std::wstring& columnName, _UINT32 listIndex, _UINT16& indexColumn);
unsigned int getColumnsCount(_UINT32 listIndex);
unsigned short AddMultysheetXti(const std::wstring& name, const _INT32& firstIxti, const _INT32& secondIxti);
unsigned int AddDefinedName(const std::wstring& name);
}

View File

@ -56,7 +56,7 @@ public:
static const ElementType type = typeFileSharing;
Boolean<unsigned short> fReadOnlyRec;
unsigned short wResPassNum = 0;
unsigned short wResPassNum;
std::wstring wResPass;
_UINT16 iNoResPass;
XLUnicodeString stUNUsername;

View File

@ -61,12 +61,12 @@ namespace XLS
static const ElementType type = typeXF;
_UINT16 font_index = 0;
_UINT16 font_index;
_UINT16 ifmt = 0; //used
std::wstring format_code = L"";
_UINT16 ifmt; //used
std::wstring format_code;
_UINT16 ixfParent = 0;
_UINT16 ixfParent;
bool fLocked = false;
bool fHidden = false;

View File

@ -1,4 +1,4 @@
/*
/*
* (c) Copyright Ascensio System SIA 2010-2021
*
* This program is a free software product. You can redistribute it and/or
@ -71,9 +71,10 @@ namespace XLSB
void FRTSqref::save(XLS::CFRecord& record)
{
_UINT32 flags = 2;
_UINT32 flags = 0;
SETBIT(flags, 0, fAdjDelete)
SETBIT(flags, 1, fDoAdjust)
SETBIT(flags, 2, fAdjChange)
SETBIT(flags, 3, fEdit)

View File

@ -82,7 +82,6 @@ OfficeArtRecordPtr OfficeArtContainer::CreateOfficeArt(unsigned short type)
case FSP:
art_record = OfficeArtRecordPtr(new OfficeArtFSP); break;
case FOPT:
case SecondaryFOPT:
art_record = OfficeArtRecordPtr(new OfficeArtFOPT); break;
case ChildAnchor:
art_record = OfficeArtRecordPtr(new OfficeArtChildAnchor); break;
@ -117,6 +116,8 @@ OfficeArtRecordPtr OfficeArtContainer::CreateOfficeArt(unsigned short type)
art_record = OfficeArtRecordPtr(new OfficeArtBStoreContainer); break;
case TertiaryFOPT:
art_record = OfficeArtRecordPtr(new OfficeArtTertiaryFOPT); break;
case SecondaryFOPT:
case FPSPL:
case FDGSL:
case FBSE:

View File

@ -317,6 +317,9 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R
[&](XLS::GlobalWorkbookInfo::_xti i) {
return i.iSup == ixti;
});
if(pos->itabFirst == pos->itabLast)
rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_VALUE, rgce.getLocation())));
else
rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation())));
}
else if(SyntaxPtg::extract_PtgRefErr(it, itEnd))

View File

@ -617,11 +617,21 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std::
}
else if (boost::regex_search(first, last, results_1, reg_inside_table6))
{
ptgList.columns = 0;
ptgList.colFirst = 0;
ptgList.colLast = 0;
ptgList.rowType = 0x00;
first = results_1[0].second;
auto colCount = XMLSTUFF::getColumnsCount(indexTable);
if(colCount>1)
{
ptgList.columns = 0x02;
ptgList.colFirst = 0;
ptgList.colLast = colCount-1;
first = results_1[0].second;
}
else
{
ptgList.columns = 0x01;
ptgList.colFirst = 0;
ptgList.colLast = 0;
first = results_1[0].second;
}
return true;
}
else if(boost::regex_search(first, last, results_1, reg_inside_table4))

View File

@ -1253,15 +1253,40 @@ allowOverlap=\"1\">";
bool CWiterTblPr::IsEmpty()
{
return Props.empty() && tblPrChange.empty() && Caption.empty() && Description.empty();
return Jc.empty() && TableInd.empty() && TableW.empty() && TableCellMar.empty() && TableBorders.empty() && Shd.empty() && tblpPr.empty()&& Style.empty() && Look.empty() && tblPrChange.empty() && TableCellSpacing.empty() && RowBandSize.empty() && ColBandSize.empty();
}
std::wstring CWiterTblPr::Write()
{
std::wstring sRes;
sRes += L"<w:tblPr>";
sRes += Props;
if (false == Style.empty())
sRes += (Style);
if (false == tblpPr.empty())
sRes += (tblpPr);
if (!RowBandSize.empty())
sRes += (RowBandSize);
if (!ColBandSize.empty())
sRes += (ColBandSize);
if (!Overlap.empty())
sRes += (Overlap);
if (false == TableW.empty())
sRes += (TableW);
if (false == Jc.empty())
sRes += (Jc);
if (false == TableCellSpacing.empty())
sRes += (TableCellSpacing);
if (false == TableInd.empty())
sRes += (TableInd);
if (false == TableBorders.empty())
sRes += (TableBorders);
if (false == Shd.empty())
sRes += (Shd);
if (false == Layout.empty())
sRes += (Layout);
if (false == TableCellMar.empty())
sRes += (TableCellMar);
if (false == Look.empty())
sRes += (Look);
if (!Caption.empty())
{
sRes += L"<w:tblCaption w:val=\"";
@ -1274,8 +1299,8 @@ allowOverlap=\"1\">";
sRes += XmlUtils::EncodeXmlString(Description);
sRes += L"\"/>";
}
sRes += tblPrChange;
if (!tblPrChange.empty())
sRes += (tblPrChange);
sRes += L"</w:tblPr>";
return sRes;
}

View File

@ -443,11 +443,24 @@ public:
class CWiterTblPr
{
public:
std::wstring Jc;
std::wstring TableInd;
std::wstring TableW;
std::wstring TableCellMar;
std::wstring TableBorders;
std::wstring Shd;
std::wstring tblpPr;
std::wstring Style;
std::wstring RowBandSize;
std::wstring ColBandSize;
std::wstring Look;
std::wstring Layout;
std::wstring tblPrChange;
std::wstring TableCellSpacing;
std::wstring Caption;
std::wstring Description;
std::wstring Overlap;
std::wstring Props;
bool IsEmpty();
std::wstring Write();
};

View File

@ -30,10 +30,10 @@
*
*/
#include "BinaryReaderD.h"
#include "Readers.h"
#include "../BinWriter/BinReaderWriterDefines.h"
#include "../../Sheets/Writer/BinaryReaderS.h"
#include "../../Sheets/Writer/BinaryReader.h"
#include "../../../PPTXFormat/Logic/HeadingVariant.h"
@ -1570,11 +1570,6 @@ int Binary_pPrReader::Read_SecPr(BYTE type, long length, void* poResult)
pSectPr->m_oDocGrid.Init();
READ1_DEF(length, res, this->ReadDocGrid, pSectPr->m_oDocGrid.GetPointer());
}
else if (c_oSerProp_secPrType::bidi == type)
{
pSectPr->m_oBidi.Init();
pSectPr->m_oBidi->m_oVal.FromBool(m_oBufferedStream.GetBool());
}
else
res = c_oSerConstants::ReadUnknown;
return res;
@ -2165,21 +2160,21 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult)
if ( c_oSerProp_tblPrType::RowBandSize == type )
{
long nRowBandSize = m_oBufferedStream.GetLong();
pWiterTblPr->Props += L"<w:tblStyleRowBandSize w:val=\"" + std::to_wstring(nRowBandSize) + L"\"/>";
pWiterTblPr->RowBandSize = L"<w:tblStyleRowBandSize w:val=\"" + std::to_wstring(nRowBandSize) + L"\"/>";
}
else if ( c_oSerProp_tblPrType::ColBandSize == type )
{
long nColBandSize = m_oBufferedStream.GetLong();
pWiterTblPr->Props += L"<w:tblStyleColBandSize w:val=\"" + std::to_wstring(nColBandSize) + L"\"/>";
pWiterTblPr->ColBandSize = L"<w:tblStyleColBandSize w:val=\"" + std::to_wstring(nColBandSize) + L"\"/>";
}
else if ( c_oSerProp_tblPrType::Jc == type )
{
BYTE jc = m_oBufferedStream.GetUChar();
switch(jc)
{
case align_Right: pWiterTblPr->Props += L"<w:jc w:val=\"right\" />"; break;
case align_Center: pWiterTblPr->Props += L"<w:jc w:val=\"center\" />"; break;
case align_Justify: pWiterTblPr->Props += L"<w:jc w:val=\"both\" />"; break;
case align_Right: pWiterTblPr->Jc = std::wstring(_T("<w:jc w:val=\"right\" />")); break;
case align_Center: pWiterTblPr->Jc = std::wstring(_T("<w:jc w:val=\"center\" />"));break;
case align_Justify: pWiterTblPr->Jc = std::wstring(_T("<w:jc w:val=\"both\" />")); break;
case align_Left: break;
}
}
@ -2187,17 +2182,17 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult)
{
double dInd = m_oBufferedStream.GetDouble();
long nInd = SerializeCommon::Round( g_dKoef_mm_to_twips * dInd);
pWiterTblPr->Props += L"<w:tblInd w:w=\"" + std::to_wstring(nInd) + L"\" w:type=\"dxa\"/>";
pWiterTblPr->TableInd = L"<w:tblInd w:w=\"" + std::to_wstring(nInd) + L"\" w:type=\"dxa\"/>";
}
else if ( c_oSerProp_tblPrType::TableIndTwips == type )
{
pWiterTblPr->Props += L"<w:tblInd w:w=\"" + std::to_wstring(m_oBufferedStream.GetLong()) + L"\" w:type=\"dxa\"/>";
pWiterTblPr->TableInd = L"<w:tblInd w:w=\"" + std::to_wstring(m_oBufferedStream.GetLong()) + L"\" w:type=\"dxa\"/>";
}
else if ( c_oSerProp_tblPrType::TableW == type )
{
docW odocW;
READ2_DEF(length, res, this->ReadW, &odocW);
pWiterTblPr->Props += odocW.Write(std::wstring(_T("w:tblW")));
pWiterTblPr->TableW = odocW.Write(std::wstring(_T("w:tblW")));
}
else if ( c_oSerProp_tblPrType::TableCellMar == type )
{
@ -2205,7 +2200,9 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult)
READ1_DEF(length, res, this->ReadCellMargins, &oTempWriter);
if (oTempWriter.GetCurSize() > 0)
{
pWiterTblPr->Props += L"<w:tblCellMar>" + oTempWriter.GetData() + L"</w:tblCellMar>";
pWiterTblPr->TableCellMar += L"<w:tblCellMar>";
pWiterTblPr->TableCellMar += oTempWriter.GetData();
pWiterTblPr->TableCellMar += L"</w:tblCellMar>";
}
}
else if ( c_oSerProp_tblPrType::TableBorders == type )
@ -2216,7 +2213,7 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult)
std::wstring sTableBorders = tblBorders.toXML();
if (false == sTableBorders.empty())
{
pWiterTblPr->Props += sTableBorders;
pWiterTblPr->TableBorders += sTableBorders;
}
}
else if ( c_oSerProp_tblPrType::Shd == type )
@ -2227,26 +2224,30 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult)
std::wstring sShd = oShd.ToString();
if (false == sShd.empty())
{
pWiterTblPr->Props += L"<w:shd " + sShd + L"/>";
pWiterTblPr->Shd = L"<w:shd " + sShd + L"/>";
}
}
else if ( c_oSerProp_tblPrType::tblpPr == type )
{
NSStringUtils::CStringBuilder oTempWriter;
READ2_DEF(length, res, this->Read_tblpPr, &oTempWriter);
pWiterTblPr->Props += L"<w:tblpPr w:vertAnchor=\"page\" w:horzAnchor=\"page\"" + oTempWriter.GetData() + L"/>";
pWiterTblPr->tblpPr += L"<w:tblpPr w:vertAnchor=\"page\" w:horzAnchor=\"page\"";
pWiterTblPr->tblpPr += oTempWriter.GetData();
pWiterTblPr->tblpPr += L"/>";
}
else if ( c_oSerProp_tblPrType::tblpPr2 == type )
{
NSStringUtils::CStringBuilder oTempWriter;
READ2_DEF(length, res, this->Read_tblpPr2, &oTempWriter);
pWiterTblPr->Props += L"<w:tblpPr" + oTempWriter.GetData() + L"/>";
pWiterTblPr->tblpPr += L"<w:tblpPr";
pWiterTblPr->tblpPr += oTempWriter.GetData();
pWiterTblPr->tblpPr += L"/>";
}
else if ( c_oSerProp_tblPrType::Style == type )
{
std::wstring Name(m_oBufferedStream.GetString3(length));
Name = XmlUtils::EncodeXmlString(Name);
pWiterTblPr->Props += L"<w:tblStyle w:val=\"" + Name + L"\"/>";
pWiterTblPr->Style = L"<w:tblStyle w:val=\"" + Name + L"\"/>";
}
else if ( c_oSerProp_tblPrType::Look == type )
{
@ -2258,7 +2259,7 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult)
int nLR = (0 == (nLook & 0x0040)) ? 0 : 1;
int nBH = (0 == (nLook & 0x0200)) ? 0 : 1;
int nBV = (0 == (nLook & 0x0400)) ? 0 : 1;
pWiterTblPr->Props += L"<w:tblLook w:val=\"" + XmlUtils::ToString(nLook, L"%04X")
pWiterTblPr->Look = L"<w:tblLook w:val=\"" + XmlUtils::ToString(nLook, L"%04X")
+ L"\" w:firstRow=\"" + std::to_wstring(nFR) + L"\" w:lastRow=\"" + std::to_wstring(nLR)
+ L"\" w:firstColumn=\"" + std::to_wstring(nFC) + L"\" w:lastColumn=\"" + std::to_wstring(nLC)
+ L"\" w:noHBand=\"" + std::to_wstring(nBH) + L"\" w:noVBand=\"" + std::to_wstring(nBV) + L"\"/>";
@ -2273,7 +2274,7 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult)
case 2: sLayout = _T("fixed");break;
}
if (false == sLayout.empty())
pWiterTblPr->Props += L"<w:tblLayout w:type=\"" + sLayout + L"\"/>";
pWiterTblPr->Layout = L"<w:tblLayout w:type=\"" + sLayout + L"\"/>";
}
else if ( c_oSerProp_tblPrType::tblPrChange == type )
{
@ -2286,11 +2287,11 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult)
double dSpacing = m_oBufferedStream.GetDouble();
dSpacing /=2;
long nSpacing = SerializeCommon::Round( g_dKoef_mm_to_twips * dSpacing);
pWiterTblPr->Props += L"<w:tblCellSpacing w:w=\"" + std::to_wstring(nSpacing) + L"\" w:type=\"dxa\"/>";
pWiterTblPr->TableCellSpacing = L"<w:tblCellSpacing w:w=\"" + std::to_wstring(nSpacing) + L"\" w:type=\"dxa\"/>";
}
else if ( c_oSerProp_tblPrType::TableCellSpacingTwips == type )
{
pWiterTblPr->Props += L"<w:tblCellSpacing w:w=\"" + std::to_wstring(m_oBufferedStream.GetLong()) + L"\" w:type=\"dxa\"/>";
pWiterTblPr->TableCellSpacing = L"<w:tblCellSpacing w:w=\"" + std::to_wstring(m_oBufferedStream.GetLong()) + L"\" w:type=\"dxa\"/>";
}
else if ( c_oSerProp_tblPrType::tblCaption == type )
{
@ -2305,15 +2306,10 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult)
BYTE jc = m_oBufferedStream.GetUChar();
switch (jc)
{
case 1: pWiterTblPr->Props += L"<w:tblOverlap w:val=\"never\" />"; break;
case 2: pWiterTblPr->Props += L"<w:tblOverlap w:val=\"overlap\" />"; break;
case 1: pWiterTblPr->Overlap = std::wstring(_T("<w:tblOverlap w:val=\"never\" />")); break;
case 2: pWiterTblPr->Overlap = std::wstring(_T("<w:tblOverlap w:val=\"overlap\" />")); break;
}
}
else if (c_oSerProp_tblPrType::bidiVisual == type)
{
bool val = m_oBufferedStream.GetBool();
if (val)
pWiterTblPr->Props += L"<w:bidiVisual/>";
}
else
res = c_oSerConstants::ReadUnknown;

View File

@ -287,8 +287,7 @@ extern int g_nCurFormatVersion;
tblDescription = 18,
TableIndTwips = 19,
TableCellSpacingTwips = 20,
tblOverlap = 21,
bidiVisual = 22
tblOverlap = 21
};}
namespace c_oSer_tblpPrType{enum c_oSer_tblpPrType
{
@ -480,8 +479,7 @@ extern int g_nCurFormatVersion;
endnotePr = 11,
rtlGutter = 12,
lnNumType = 13,
docGrid = 14,
bidi = 15
docGrid = 14
};}
namespace c_oSerProp_secPrSettingsType{enum c_oSerProp_secPrSettingsType
{

View File

@ -29,7 +29,7 @@
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "BinaryWriterD.h"
#include "BinWriters.h"
#include "../DocWrapper/FontProcessor.h"
#include "../../../../Common/Base64.h"
@ -37,7 +37,7 @@
#include "../../Presentation/FontCutter.h"
#include "../../../PPTXFormat/Logic/HeadingVariant.h"
#include "../../Sheets/Reader/BinaryWriterS.h"
#include "../../Sheets/Reader/BinaryWriter.h"
#include "BinEquationWriter.h"
#include "../../../../OfficeUtils/src/OfficeUtils.h"
@ -1559,12 +1559,6 @@ void Binary_pPrWriter::WriteSectPr (OOX::Logic::CSectionProperty* pSectPr)
WriteDocGrid(pSectPr->m_oDocGrid.get());
m_oBcw.WriteItemEnd(nCurPos);
}
if (pSectPr->m_oBidi.IsInit())
{
nCurPos = m_oBcw.WriteItemStart(c_oSerProp_secPrType::bidi);
m_oBcw.m_oStream.WriteBOOL(pSectPr->m_oBidi->m_oVal.ToBool());
m_oBcw.WriteItemEnd(nCurPos);
}
}
void Binary_pPrWriter::WritePageSettings(OOX::Logic::CSectionProperty* pSectPr)
{
@ -2164,12 +2158,14 @@ void Binary_tblPrWriter::WriteTblPr(OOX::Logic::CTableProperty* p_tblPr)
m_oBcw.m_oStream.WriteBYTE(c_oSerProp_tblPrType::Style);
m_oBcw.m_oStream.WriteStringW(p_tblPr->m_oTblStyle->ToString2());
}
//Look
if (p_tblPr->m_oTblLook.IsInit())
{
nCurPos = m_oBcw.WriteItemStart(c_oSerProp_tblPrType::Look);
m_oBcw.m_oStream.WriteLONG(p_tblPr->m_oTblLook->GetValue());
m_oBcw.WriteItemEnd(nCurPos);
}
//Layout
if (p_tblPr->m_oTblLayout.IsInit() && p_tblPr->m_oTblLayout->m_oType.IsInit())
{
nCurPos = m_oBcw.WriteItemStart(c_oSerProp_tblPrType::Layout);
@ -2216,12 +2212,7 @@ void Binary_tblPrWriter::WriteTblPr(OOX::Logic::CTableProperty* p_tblPr)
m_oBcw.m_oStream.WriteBYTE((BYTE)p_tblPr->m_oTblOverlap->m_oVal->GetValue());
m_oBcw.WriteItemEnd(nCurPos);
}
if (p_tblPr->m_oBidiVisual.IsInit())
{
nCurPos = m_oBcw.WriteItemStart(c_oSerProp_tblPrType::bidiVisual);
m_oBcw.m_oStream.WriteBOOL(p_tblPr->m_oBidiVisual->m_oVal.ToBool());
m_oBcw.WriteItemEnd(nCurPos);
}}
}
void Binary_tblPrWriter::WriteTblMar(const OOX::Logic::CTblCellMar& cellMar)
{
int nCurPos = 0;
@ -5119,16 +5110,16 @@ void BinaryDocumentTableWriter::WriteMathRunContent(OOX::Logic::CMRun* pMRun)
int nBreakType = -1;
switch (pBr->m_oType.GetValue())
{
case SimpleTypes::brtypeColumn: nBreakType = c_oSer_OMathContentType::columnbreak; break;
case SimpleTypes::brtypePage: nBreakType = c_oSer_OMathContentType::pagebreak; break;
case SimpleTypes::brtypeColumn: nBreakType = c_oSerRunType::columnbreak; break;
case SimpleTypes::brtypePage: nBreakType = c_oSerRunType::pagebreak; break;
case SimpleTypes::brtypeTextWrapping:
{
switch (pBr->m_oClear.GetValue())
{
//case SimpleTypes::brclearAll: nBreakType = c_oSer_OMathContentType::linebreakClearAll; break;
//case SimpleTypes::brclearLeft: nBreakType = c_oSer_OMathContentType::linebreakClearLeft; break;
//case SimpleTypes::brclearRight: nBreakType = c_oSer_OMathContentType::linebreakClearRight; break;
default: nBreakType = c_oSer_OMathContentType::linebreak; break;
case SimpleTypes::brclearAll: nBreakType = c_oSerRunType::linebreakClearAll; break;
case SimpleTypes::brclearLeft: nBreakType = c_oSerRunType::linebreakClearLeft; break;
case SimpleTypes::brclearRight: nBreakType = c_oSerRunType::linebreakClearRight; break;
default: nBreakType = c_oSerRunType::linebreak; break;
}
}break;

View File

@ -31,8 +31,8 @@
*/
#include "DocxSerializer.h"
#include "../BinWriter/BinaryWriterD.h"
#include "../BinReader/BinaryReaderD.h"
#include "../BinWriter/BinWriters.h"
#include "../BinReader/Readers.h"
#include "../../../PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.h"
#include "../../Presentation/FontPicker.h"

View File

@ -1,141 +0,0 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "VsdxSerializer.h"
#include "../../../../DesktopEditor/common/Directory.h"
#include "../../../../DesktopEditor/common/File.h"
#include "../../../../DesktopEditor/common/Path.h"
#include "../../Draw/BinaryWriterV.h"
#include "../../Draw/BinaryReaderV.h"
#include "../../Presentation/FontPicker.h"
#include "../../../../OfficeUtils/src/OfficeUtils.h"
namespace BinVsdxRW
{
int g_nCurFormatVersion = 0;
CVsdxSerializer::CVsdxSerializer() : m_bIsMacro(false), m_bIsNoBase64(false)
{
m_pExternalDrawingConverter = NULL;
}
CVsdxSerializer::~CVsdxSerializer()
{
}
void CVsdxSerializer::CreateVsdxFolders(const std::wstring& sDstPath, std::wstring& sMediaPath, std::wstring& sEmbedPath)
{
OOX::CPath pathMediaDir = sDstPath + FILE_SEPARATOR_STR + _T("visio") + FILE_SEPARATOR_STR + _T("media");
OOX::CPath pathEmbedDir = sDstPath + FILE_SEPARATOR_STR + _T("visio") + FILE_SEPARATOR_STR + _T("embeddings");
//создавать папку надо даже при сохранении в csv, потому что когда читаем из бинарника тему, она записывается в файл.
OOX::CPath pathVDir = sDstPath + FILE_SEPARATOR_STR + _T("visio");
OOX::CPath pathThemeDir = pathVDir + FILE_SEPARATOR_STR + OOX::FileTypes::Theme.DefaultDirectory().GetPath();
OOX::CPath pathThemeFile = pathThemeDir + FILE_SEPARATOR_STR + OOX::FileTypes::Theme.DefaultFileName().GetPath();
OOX::CPath pathThemeThemeRelsDir = pathThemeDir + FILE_SEPARATOR_STR + _T("_rels");
NSDirectory::CreateDirectory(pathVDir.GetPath());
NSDirectory::CreateDirectory(pathThemeDir.GetPath());
NSDirectory::CreateDirectory(pathThemeThemeRelsDir.GetPath());
NSDirectory::CreateDirectory(pathMediaDir.GetPath());
NSDirectory::CreateDirectory(pathEmbedDir.GetPath());
sMediaPath = pathMediaDir.GetPath();
sEmbedPath = pathEmbedDir.GetPath();
}
_UINT32 CVsdxSerializer::loadFromFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sMediaDir, const std::wstring& sEmbedDir)
{
std::wstring strFileInDir = NSSystemPath::GetDirectoryName(sSrcFileName);
NSBinPptxRW::CDrawingConverter oDrawingConverter;
oDrawingConverter.SetDstPath(sDstPath + FILE_SEPARATOR_STR + L"visio");
oDrawingConverter.SetSrcPath(strFileInDir, XMLWRITER_DOC_TYPE_VSDX);
oDrawingConverter.SetMediaDstPath(sMediaDir);
oDrawingConverter.SetEmbedDstPath(sEmbedDir);
oDrawingConverter.SetTempPath(m_sTempDir);
BinVsdxRW::BinaryFileReader oBinaryFileReader;
return oBinaryFileReader.ReadFile(sSrcFileName, sDstPath, &oDrawingConverter, m_bIsMacro);
}
_UINT32 CVsdxSerializer::saveToFile(const std::wstring& sDstFileName, const std::wstring& sSrcPath)
{
COfficeFontPicker* pFontPicker = new COfficeFontPicker();
pFontPicker->Init(m_sFontDir);
NSFonts::IFontManager* pFontManager = pFontPicker->get_FontManager();
DocWrapper::FontProcessor fp;
fp.setFontManager(pFontManager);
NSBinPptxRW::CDrawingConverter oOfficeDrawingConverter;
oOfficeDrawingConverter.SetFontManager(pFontManager);
oOfficeDrawingConverter.SetFontDir(m_sFontDir);
oOfficeDrawingConverter.SetFontPicker(pFontPicker);
BinVsdxRW::BinaryFileWriter oBinaryFileWriter(fp);
_UINT32 result = oBinaryFileWriter.Open(sSrcPath, sDstFileName, &oOfficeDrawingConverter, m_bIsNoBase64);
RELEASEOBJECT(pFontPicker);
return result;
}
void CVsdxSerializer::setTempDir(const std::wstring& sTempDir)
{
m_sTempDir = sTempDir;
}
void CVsdxSerializer::setFontDir(const std::wstring& sFontDir)
{
m_sFontDir = sFontDir;
}
void CVsdxSerializer::setEmbeddedFontsDir(const std::wstring& sEmbeddedFontsDir)
{
m_sEmbeddedFontsDir = sEmbeddedFontsDir;
}
void CVsdxSerializer::setDrawingConverter(NSBinPptxRW::CDrawingConverter* pDrawingConverter)
{
m_pExternalDrawingConverter = pDrawingConverter;
}
void CVsdxSerializer::setIsNoBase64(bool val)
{
m_bIsNoBase64 = val;
}
void CVsdxSerializer::setMacroEnabled(bool val)
{
m_bIsMacro = val;
}
bool CVsdxSerializer::getMacroEnabled()
{
return m_bIsMacro;
}
};

View File

@ -1,78 +0,0 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#pragma once
#include <string>
#include "../../../Base/Base.h"
#include "../../../Base/SmartPtr.h"
namespace OOX
{
class File;
}
namespace NSBinPptxRW{
class CDrawingConverter;
}
namespace NSBinPptxRW{
class CBinaryFileReader;
class CBinaryFileWriter;
}
namespace BinVsdxRW {
class CVsdxSerializer
{
private:
std::wstring m_sTempDir;
std::wstring m_sFontDir;
std::wstring m_sEmbeddedFontsDir;
NSBinPptxRW::CDrawingConverter* m_pExternalDrawingConverter;
bool m_bIsNoBase64;
bool m_bIsMacro;
public:
CVsdxSerializer();
~CVsdxSerializer();
_UINT32 loadFromFile (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sMediaDir, const std::wstring& sEmbedPath);
_UINT32 saveToFile (const std::wstring& sDstPath, const std::wstring& sSrcFileName);
//------------------------------------------------
static void CreateVsdxFolders (const std::wstring& sDstPath, std::wstring& sMediaPath, std::wstring& sEmbedPath);
void setTempDir (const std::wstring& sTempDir);
void setFontDir (const std::wstring& sFontDir);
void setEmbeddedFontsDir(const std::wstring& sEmbeddedFontsDir);
void setDrawingConverter(NSBinPptxRW::CDrawingConverter* pDrawingConverter);
void setIsNoBase64 (bool val);
void setMacroEnabled (bool val);
bool getMacroEnabled ();
};
}

View File

@ -37,8 +37,8 @@
#include "../../../XlsxFormat/Chart/Chart.h"
#include "../../Sheets/Reader/BinaryWriterS.h"
#include "../../Sheets/Writer/BinaryReaderS.h"
#include "../../Sheets/Reader/BinaryWriter.h"
#include "../../Sheets/Writer/BinaryReader.h"
#include "../../Presentation/FontPicker.h"
#include "../../../../OfficeUtils/src/OfficeUtils.h"
@ -93,7 +93,7 @@ namespace BinXlsxRW{
NSBinPptxRW::CDrawingConverter oDrawingConverter;
oDrawingConverter.SetDstPath(sDstPath + FILE_SEPARATOR_STR + L"xl");
oDrawingConverter.SetSrcPath(strFileInDir, XMLWRITER_DOC_TYPE_XLSX);
oDrawingConverter.SetSrcPath(strFileInDir, 2);
oDrawingConverter.SetMediaDstPath(sMediaDir);
oDrawingConverter.SetEmbedDstPath(sEmbedDir);
@ -150,7 +150,7 @@ namespace BinXlsxRW{
NSBinPptxRW::CDrawingConverter oDrawingConverter;
oDrawingConverter.SetDstPath(sDstPath + FILE_SEPARATOR_STR + L"xl");
oDrawingConverter.SetSrcPath(strFileInDir, XMLWRITER_DOC_TYPE_XLSX);
oDrawingConverter.SetSrcPath(strFileInDir, 2);
oDrawingConverter.SetFontDir(m_sFontDir);
BinXlsxRW::BinaryFileReader oBinaryFileReader;
@ -324,4 +324,11 @@ namespace BinXlsxRW{
NSDirectory::DeleteDirectory(sTempDir);
return res;
}
bool CXlsxSerializer::hasPivot(const std::wstring& sSrcPath)
{
//todo CXlsx
std::wstring sData;
NSFile::CFileBinary::ReadAllTextUtf8(sSrcPath + FILE_SEPARATOR_STR + L"[Content_Types].xml", sData);
return std::wstring::npos != sData.find(OOX::Spreadsheet::FileTypes::PivotTable.OverrideType());
}
};

View File

@ -79,5 +79,6 @@ namespace BinXlsxRW {
bool saveChart (NSBinPptxRW::CBinaryFileReader* pReader, long lLength, NSCommon::smart_ptr<OOX::File> &file);
bool writeChartXlsx (const std::wstring& sDstFile, NSCommon::smart_ptr<OOX::File> &file);
bool hasPivot (const std::wstring& sSrcPath);
};
}

View File

@ -1,69 +0,0 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#pragma once
namespace BinVsdxRW
{
const static wchar_t* g_sFormatSignature = L"VSDY";
const int g_nFormatVersion = 1;
const int g_nFormatVersionNoBase64 = 1;
extern int g_nCurFormatVersion;
namespace c_oSerConstants{enum c_oSerConstants
{
ErrorFormat = -2,
ErrorUnknown = -1,
ReadOk = 0,
ReadUnknown = 1,
ErrorStream = 0x55
};}
namespace c_oSerPropLenType{enum c_oSerPropLenType
{
Null = 0,
Byte = 1,
Short = 2,
Three = 3,
Long = 4,
Double = 5,
Variable = 6,
Double64 = 7,
Long64 = 8
};}
namespace c_oSerTableTypes{enum c_oSerTableTypes
{
Document = 1,
App = 2,
Core = 3,
CustomProperties = 4
};}
}

View File

@ -1,287 +0,0 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "BinaryReaderV.h"
#include "../../../Common/Base64.h"
#include "../../../Common/ATLDefine.h"
#include "../../../Common/OfficeFileErrorDescription.h"
#include "../../../DesktopEditor/common/Path.h"
#include "../../../DesktopEditor/common/Directory.h"
#include "../../../DesktopEditor/raster/ImageFileFormatChecker.h"
#include "../../PPTXFormat/Theme.h"
#include "../../PPTXFormat/Logic/HeadingVariant.h"
#include "../../PPTXFormat/Logic/Shape.h"
#include "../../DocxFormat/Media/VbaProject.h"
#include "../../DocxFormat/Media/JsaProject.h"
#include "../../DocxFormat/App.h"
#include "../../DocxFormat/Core.h"
#include "../../DocxFormat/CustomXml.h"
#include "../../VsdxFormat/Vsdx.h"
#include "../../VsdxFormat/VisioDocument.h"
namespace BinVsdxRW
{
SaveParams::SaveParams(bool bMacro) : bMacroEnabled(bMacro)
{
}
BinaryFileReader::BinaryFileReader()
{
}
int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, bool &bMacro)
{
bool bResultOk = false;
NSFile::CFileBinary oFile;
if (false == oFile.OpenFile(sSrcFileName)) return AVS_FILEUTILS_ERROR_CONVERT;
NSBinPptxRW::CBinaryFileReader& oBufferedStream = *pOfficeDrawingConverter->m_pReader;
DWORD nBase64DataSize = 0;
BYTE* pBase64Data = new BYTE[oFile.GetFileSize()];
oFile.ReadFile(pBase64Data, oFile.GetFileSize(), nBase64DataSize);
oFile.CloseFile();
//проверяем формат
bool bValidFormat = false;
std::wstring sSignature(g_sFormatSignature);
size_t nSigLength = sSignature.length();
if (nBase64DataSize > nSigLength)
{
std::string sCurSig((char*)pBase64Data, nSigLength);
std::wstring wsCurSig(sCurSig.begin(), sCurSig.end());
if (sSignature == wsCurSig)
{
bValidFormat = true;
}
}
if (bValidFormat)
{
//Читаем из файла версию и длину base64
int nIndex = (int)nSigLength;
int nType = 0;
std::string version = "";
std::string dst_len = "";
while (nIndex < nBase64DataSize)
{
nIndex++;
BYTE _c = pBase64Data[nIndex];
if (_c == ';')
{
if (0 == nType)
{
nType = 1;
continue;
}
else
{
nIndex++;
break;
}
}
if (0 == nType)
version += _c;
else
dst_len += _c;
}
int nVersion = g_nFormatVersion;
if (!version.empty())
{
version = version.substr(1);
g_nCurFormatVersion = nVersion = std::stoi(version.c_str());
}
bool bIsNoBase64 = nVersion == g_nFormatVersionNoBase64;
int nDataSize = 0;
BYTE* pData = NULL;
if (!bIsNoBase64)
{
nDataSize = atoi(dst_len.c_str());
pData = new BYTE[nDataSize];
if (Base64::Base64Decode((const char*)(pBase64Data + nIndex), nBase64DataSize - nIndex, pData, &nDataSize))
{
oBufferedStream.Init(pData, 0, nDataSize);
}
else
{
RELEASEARRAYOBJECTS(pData);
}
}
else
{
nDataSize = nBase64DataSize;
pData = pBase64Data;
oBufferedStream.Init(pData, 0, nDataSize);
oBufferedStream.Seek(nIndex);
}
if (NULL != pData)
{
bResultOk = true;
OOX::Draw::CVsdx oVsdx;
SaveParams oSaveParams(bMacro);
try
{
ReadContent(oVsdx, oBufferedStream, OOX::CPath(sSrcFileName).GetDirectory(), sDstPath, oSaveParams);
}
catch (...)
{
bResultOk = false;
}
OOX::CContentTypes oContentTypes;
oVsdx.Write(sDstPath, oContentTypes);
bMacro = oSaveParams.bMacroEnabled;
}
if (!bIsNoBase64)
{
RELEASEARRAYOBJECTS(pData);
}
}
RELEASEARRAYOBJECTS(pBase64Data);
if (bResultOk) return 0;
else return AVS_FILEUTILS_ERROR_CONVERT;
}
int BinaryFileReader::ReadContent(OOX::Draw::CVsdx& oVsdx, NSBinPptxRW::CBinaryFileReader& oBufferedStream, const std::wstring& sFileInDir, const std::wstring& sOutDir, SaveParams& oSaveParams)
{
long res = oBufferedStream.Peek(1) == false ? c_oSerConstants::ErrorStream : c_oSerConstants::ReadOk;
if (c_oSerConstants::ReadOk != res)
return res;
OOX::CPath pathMedia = sOutDir + FILE_SEPARATOR_STR + L"visio" + FILE_SEPARATOR_STR + L"media";
OOX::CPath pathEmbeddings = sOutDir + FILE_SEPARATOR_STR + L"visio" + FILE_SEPARATOR_STR + L"embeddings";
oBufferedStream.m_nDocumentType = XMLWRITER_DOC_TYPE_VSDX;
oBufferedStream.m_strFolder = sFileInDir;
oBufferedStream.m_pRels->m_pManager->m_nDocumentType = XMLWRITER_DOC_TYPE_VSDX;
oBufferedStream.m_pRels->m_pManager->SetDstMedia(pathMedia.GetPath());
oBufferedStream.m_pRels->m_pManager->SetDstEmbed(pathEmbeddings.GetPath());
std::vector<BYTE> aTypes;
std::vector<long> aOffBits;
BYTE mtLen = oBufferedStream.GetUChar();
for (int i = 0; i < mtLen; ++i)
{
//mtItem
res = oBufferedStream.Peek(5) == false ? c_oSerConstants::ErrorStream : c_oSerConstants::ReadOk;
if (c_oSerConstants::ReadOk != res)
return res;
BYTE mtiType = 0;
if (false == oBufferedStream.GetUCharWithResult(&mtiType))
break;
long mtiOffBits = oBufferedStream.GetLong();
aTypes.push_back(mtiType);
aOffBits.push_back(mtiOffBits);
}
//sOutDir
for (size_t i = 0, length = aTypes.size(); i < length; ++i)
{
BYTE mtiType = aTypes[i];
long mtiOffBits = aOffBits[i];
oBufferedStream.Seek(mtiOffBits);
switch(mtiType)
{
case c_oSerTableTypes::App:
{
OOX::CApp* pApp = new OOX::CApp(NULL);
smart_ptr<OOX::File> oCurFile(pApp);
oVsdx.m_pApp = oCurFile.smart_dynamic_cast<OOX::CApp>();
pApp->fromPPTY(&oBufferedStream);
pApp->SetRequiredDefaults();
oVsdx.Add(oCurFile);
}break;
case c_oSerTableTypes::Core:
{
OOX::CCore* pCore = new OOX::CCore(NULL);
smart_ptr<OOX::File> oCurFile(pCore);
oVsdx.m_pCore = oCurFile.smart_dynamic_cast<OOX::CCore>();
pCore->fromPPTY(&oBufferedStream);
pCore->SetRequiredDefaults();
oVsdx.Add(oCurFile);
}break;
case c_oSerTableTypes::CustomProperties:
{
PPTX::CustomProperties* oCustomProperties = new PPTX::CustomProperties(NULL);
oCustomProperties->fromPPTY(&oBufferedStream);
smart_ptr<OOX::File> oCurFile(oCustomProperties);
oVsdx.Add(oCurFile);
}break;
case c_oSerTableTypes::Document:
{
OOX::Draw::CDocumentFile* pDocument = new OOX::Draw::CDocumentFile(&oVsdx);
pDocument->m_bMacroEnabled = oSaveParams.bMacroEnabled;
smart_ptr<OOX::File> oCurFile(pDocument);
oVsdx.m_pDocument = oCurFile.smart_dynamic_cast<OOX::Draw::CDocumentFile>();
pDocument->fromPPTY(&oBufferedStream);
oVsdx.Add(oCurFile);
oSaveParams.bMacroEnabled = pDocument->m_bMacroEnabled;
}break;
}
if (c_oSerConstants::ReadOk != res)
return res;
}
return res;
}
}

View File

@ -1,58 +0,0 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#pragma once
#include <unordered_map>
#include "BinReaderWriterDefines.h"
#include "../Presentation/BinaryFileReaderWriter.h"
#include "../Presentation/BinReaderWriterDefines.h"
#include "../../PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.h"
#include "../../VsdxFormat/Vsdx.h"
namespace BinVsdxRW
{
struct SaveParams
{
SaveParams(bool bMacro = false);
bool bMacroEnabled = false;
};
class BinaryFileReader
{
public:
BinaryFileReader();
int ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, bool &bMacro);
int ReadContent(OOX::Draw::CVsdx& oVsdx, NSBinPptxRW::CBinaryFileReader& oBufferedStream, const std::wstring& sFileInDir, const std::wstring& sOutDir, SaveParams& oSaveParams);
};
}

View File

@ -1,265 +0,0 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "BinaryWriterV.h"
#include "BinaryReaderV.h"
#include "../../../Common/OfficeFileFormats.h"
#include "../../../Common/Base64.h"
#include "../../../Common/OfficeFileErrorDescription.h"
#include "../Presentation/FontCutter.h"
#include "../../PPTXFormat/Logic/HeadingVariant.h"
#include "../../PPTXFormat/Logic/Shape.h"
#include "../../VsdxFormat/Vsdx.h"
#include "../../VsdxFormat/VisioDocument.h"
#include "../../SystemUtility/SystemUtility.h"
#include "../../DocxFormat/Media/OleObject.h"
#include "../../DocxFormat/Media/ActiveX.h"
#include "../../DocxFormat/Media/VbaProject.h"
#include "../../DocxFormat/App.h"
#include "../../DocxFormat/Core.h"
//#include "../../DocxFormat/CustomXml.h"
#include "../../../DesktopEditor/common/Directory.h"
#include "../../../Common/OfficeFileFormatChecker.h"
#include "../../../OfficeUtils/src/OfficeUtils.h"
namespace BinVsdxRW
{
BinaryCommonWriter::BinaryCommonWriter(NSBinPptxRW::CBinaryFileWriter& oCBufferedStream) :m_oStream(oCBufferedStream)
{
}
int BinaryCommonWriter::WriteItemStart(BYTE type)
{
m_oStream.WriteBYTE(type);
return WriteItemWithLengthStart();
}
void BinaryCommonWriter::WriteItemEnd(int nStart)
{
WriteItemWithLengthEnd(nStart);
}
int BinaryCommonWriter::WriteItemWithLengthStart()
{
int nStartPos = m_oStream.GetPosition();
m_oStream.Skip(4);
return nStartPos;
}
void BinaryCommonWriter::WriteItemWithLengthEnd(int nStart)
{
int nEnd = m_oStream.GetPosition();
m_oStream.SetPosition(nStart);
m_oStream.WriteLONG(nEnd - nStart - 4);
m_oStream.SetPosition(nEnd);
}
void BinaryCommonWriter::WriteBytesArray(BYTE* pData, long nDataSize)
{
int nCurPos = WriteItemWithLengthStart();
m_oStream.WriteBYTEArray(pData, nDataSize);
WriteItemWithLengthEnd(nCurPos);
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BinaryFileWriter::BinaryFileWriter(DocWrapper::FontProcessor& oFontProcessor) : m_oBcw(NULL), m_oFontProcessor(oFontProcessor)
{
m_nRealTableCount = 0;
}
BinaryFileWriter::~BinaryFileWriter()
{
RELEASEOBJECT(m_oBcw);
}
_UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring& sFileDst, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, bool bIsNoBase64)
{
_UINT32 result = 0;
OOX::CPath pathDst(sFileDst);
//создаем папку для media
std::wstring mediaDir = pathDst.GetDirectory() + L"media";
NSDirectory::CreateDirectory(mediaDir);
pOfficeDrawingConverter->SetDstPath(pathDst.GetDirectory() + FILE_SEPARATOR_STR + L"visio");
pOfficeDrawingConverter->SetMediaDstPath(mediaDir);
NSBinPptxRW::CBinaryFileWriter& oBufferedStream = *pOfficeDrawingConverter->m_pBinaryWriter;
oBufferedStream.m_strMainFolder = pathDst.GetDirectory();
m_oBcw = new BinaryCommonWriter(oBufferedStream);
OOX::Draw::CVsdx *pVsdx = new OOX::Draw::CVsdx(OOX::CPath(sInputDir));
if (0 != result)
{
RELEASEOBJECT(pVsdx);
return result;
}
if (bIsNoBase64)
{
oBufferedStream.WriteStringUtf8(WriteFileHeader(0, g_nFormatVersionNoBase64));
}
int nHeaderLen = oBufferedStream.GetPosition();
WriteMainTableStart(oBufferedStream);
WriteContent(pVsdx, pOfficeDrawingConverter);
WriteMainTableEnd();
BYTE* pbBinBuffer = oBufferedStream.GetBuffer();
int nBinBufferLen = oBufferedStream.GetPosition();
if (bIsNoBase64)
{
NSFile::CFileBinary oFile;
oFile.CreateFileW(sFileDst);
//write header and main table
oFile.WriteFile(pbBinBuffer, nBinBufferLen);
oFile.CloseFile();
}
else
{
int nBase64BufferLen = Base64::Base64EncodeGetRequiredLength(nBinBufferLen, Base64::B64_BASE64_FLAG_NOCRLF);
BYTE* pbBase64Buffer = new BYTE[nBase64BufferLen + 64];
if (true == Base64_1::Base64Encode(pbBinBuffer, nBinBufferLen, pbBase64Buffer, &nBase64BufferLen))
{
NSFile::CFileBinary oFile;
oFile.CreateFileW(sFileDst);
oFile.WriteStringUTF8(WriteFileHeader(nBinBufferLen, g_nFormatVersion));
oFile.WriteFile(pbBase64Buffer, nBase64BufferLen);
oFile.CloseFile();
}
else
{
result = AVS_FILEUTILS_ERROR_CONVERT;
}
RELEASEARRAYOBJECTS(pbBase64Buffer);
}
RELEASEOBJECT(pVsdx);
return result;
}
void BinaryFileWriter::WriteContent(OOX::Document *pDocument, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter)
{
OOX::Draw::CVsdx *pVsdx = dynamic_cast<OOX::Draw::CVsdx*>(pDocument);
if (!pVsdx) return;
int nCurPos = 0;
if (pVsdx->m_pApp.IsInit())
{
nCurPos = WriteTableStart(c_oSerTableTypes::App);
pVsdx->m_pApp->toPPTY(&m_oBcw->m_oStream);
this->WriteTableEnd(nCurPos);
}
if (pVsdx->m_pCore.IsInit())
{
nCurPos = WriteTableStart(c_oSerTableTypes::Core);
pVsdx->m_pCore->toPPTY(&m_oBcw->m_oStream);
this->WriteTableEnd(nCurPos);
}
smart_ptr<OOX::File> pFile = pVsdx->Find(OOX::FileTypes::CustomProperties);
PPTX::CustomProperties *pCustomProperties = dynamic_cast<PPTX::CustomProperties*>(pFile.GetPointer());
if (pCustomProperties)
{
nCurPos = WriteTableStart(c_oSerTableTypes::CustomProperties);
pCustomProperties->toPPTY(&m_oBcw->m_oStream);
this->WriteTableEnd(nCurPos);
}
if (pVsdx->m_pDocument.IsInit())
{
nCurPos = WriteTableStart(c_oSerTableTypes::Document);
pVsdx->m_pDocument->toPPTY(&m_oBcw->m_oStream);
WriteTableEnd(nCurPos);
}
}
std::wstring BinaryFileWriter::WriteFileHeader(int nDataSize, int version)
{
std::wstring sHeader = std::wstring(g_sFormatSignature) + L";v" + std::to_wstring(version)+ L";" + std::to_wstring(nDataSize) + L";";
return sHeader;
}
void BinaryFileWriter::WriteMainTableStart(NSBinPptxRW::CBinaryFileWriter &oBufferedStream)
{
if (!m_oBcw)
m_oBcw = new BinaryCommonWriter(oBufferedStream);
m_nRealTableCount = 0;
m_nMainTableStart = m_oBcw->m_oStream.GetPosition();
//вычисляем с какой позиции можно писать таблицы
m_nLastFilePos = m_nMainTableStart + GetMainTableSize();
//Write mtLen
m_oBcw->m_oStream.WriteBYTE(0);
}
int BinaryFileWriter::GetMainTableSize()
{
return 128 * 5;//128 items of 5 bytes
}
void BinaryFileWriter::WriteMainTableEnd()
{
m_oBcw->m_oStream.SetPosition(m_nMainTableStart);
m_oBcw->m_oStream.WriteBYTE(m_nRealTableCount);
m_oBcw->m_oStream.SetPosition(m_nLastFilePos);
}
int BinaryFileWriter::WriteTableStart(BYTE type, int nStartPos)
{
if(-1 != nStartPos)
m_oBcw->m_oStream.SetPosition(nStartPos);
//Write mtItem
//Write mtiType
m_oBcw->m_oStream.WriteBYTE(type);
//Write mtiOffBits
m_oBcw->m_oStream.WriteLONG(m_nLastFilePos);
//Write table
//Запоминаем позицию в MainTable
int nCurPos = m_oBcw->m_oStream.GetPosition();
//Seek в свободную область
m_oBcw->m_oStream.SetPosition(m_nLastFilePos);
return nCurPos;
}
void BinaryFileWriter::WriteTableEnd(int nCurPos)
{
//сдвигаем позицию куда можно следующую таблицу
m_nLastFilePos = m_oBcw->m_oStream.GetPosition();
m_nRealTableCount++;
//Seek вобратно в MainTable
m_oBcw->m_oStream.SetPosition(nCurPos);
}
}

View File

@ -1,92 +0,0 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#pragma once
#include "BinReaderWriterDefines.h"
#include "../Presentation/BinaryFileReaderWriter.h"
#include "../Presentation/BinReaderWriterDefines.h"
#include "../Document/DocWrapper/FontProcessor.h"
#include "../../PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.h"
#include "../../VsdxFormat/Vsdx.h"
#include "../../../DesktopEditor/common/Directory.h"
namespace OOX
{
namespace Visio
{
class CVsdx;
class CDocument;
}
}
namespace BinVsdxRW
{
class BinaryCommonWriter
{
public:
NSBinPptxRW::CBinaryFileWriter& m_oStream;
BinaryCommonWriter(NSBinPptxRW::CBinaryFileWriter& oCBufferedStream);
int WriteItemStart(BYTE type);
void WriteItemEnd(int nStart);
int WriteItemWithLengthStart();
void WriteItemWithLengthEnd(int nStart);
void WriteBytesArray(BYTE* pData, long nDataSize);
};
class BinaryFileWriter
{
private:
BinaryCommonWriter* m_oBcw;
int m_nLastFilePos;
int m_nMainTableStart;
int m_nRealTableCount = 0;
DocWrapper::FontProcessor& m_oFontProcessor;
public:
BinaryFileWriter(DocWrapper::FontProcessor& oFontProcessor);
~BinaryFileWriter();
_UINT32 Open(const std::wstring& sInputDir, const std::wstring& sFileDst, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, bool bIsNoBase64);
void WriteMainTableStart(NSBinPptxRW::CBinaryFileWriter &oBufferedStream);
void WriteContent(OOX::Document *pDocument, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter);
void WriteMainTableEnd();
std::wstring WriteFileHeader(int nDataSize, int version);
int GetMainTableSize();
private:
int WriteTableStart(BYTE type, int nStartPos = -1);
void WriteTableEnd(int nCurPos);
};
}

View File

@ -307,7 +307,6 @@ static std::wstring SchemeClr_GetStringCode(const BYTE& val)
#define XMLWRITER_DOC_TYPE_DOCX_GLOSSARY 7
#define XMLWRITER_DOC_TYPE_DIAGRAM 8
#define XMLWRITER_DOC_TYPE_DSP_DRAWING 9
#define XMLWRITER_DOC_TYPE_VSDX 10
#define XMLWRITER_RECORD_TYPE_SPPR 0
#define XMLWRITER_RECORD_TYPE_CLRMAPOVR 1

View File

@ -1821,12 +1821,10 @@ namespace NSBinPptxRW
m_pRels = new CRelsGenerator();
m_nCurrentRelsStack = -1;
m_pCurrentContainer = new NSCommon::smart_ptr<OOX::IFileContainer>();
}
CBinaryFileReader::~CBinaryFileReader()
{
RELEASEOBJECT(m_pRels);
RELEASEOBJECT(m_pCurrentContainer);
size_t nCountStackRels = m_stackRels.size();
for (size_t i = 0; i < nCountStackRels; ++i)
@ -1836,19 +1834,7 @@ namespace NSBinPptxRW
}
m_stackRels.clear();
}
void CBinaryFileReader::SetRels(NSCommon::smart_ptr<OOX::IFileContainer> container)
{
*m_pCurrentContainer = container;
}
void CBinaryFileReader::SetRels(OOX::IFileContainer* container)
{
*m_pCurrentContainer = NSCommon::smart_ptr<OOX::IFileContainer>(container);
m_pCurrentContainer->AddRef();
}
NSCommon::smart_ptr<OOX::IFileContainer> CBinaryFileReader::GetRels()
{
return *m_pCurrentContainer;
}
void CBinaryFileReader::SetMainDocument(BinDocxRW::CDocxSerializer* pMainDoc)
{
m_pMainDocument = pMainDoc;

View File

@ -515,23 +515,17 @@ namespace NSBinPptxRW
class CBinaryFileReader
{
protected:
BYTE* m_pData = NULL;
BYTE* m_pData;
LONG m_lSize;
LONG m_lPos;
BYTE* m_pDataCur = NULL;
BYTE* m_pDataCur;
_INT32 m_lNextId;
std::vector<CRelsGenerator*> m_stackRels;
int m_nCurrentRelsStack;
NSCommon::smart_ptr<OOX::IFileContainer>* m_pCurrentContainer = NULL;
std::vector<CRelsGenerator*> m_stackRels;
int m_nCurrentRelsStack;
public:
void SetRels(NSCommon::smart_ptr<OOX::IFileContainer> container);
void SetRels(OOX::IFileContainer* container);
NSCommon::smart_ptr<OOX::IFileContainer> GetRels();
CRelsGenerator* m_pRels = NULL;
CRelsGenerator* m_pRels;
std::wstring m_strFolder;
std::wstring m_strFolderThemes;
@ -543,7 +537,7 @@ namespace NSBinPptxRW
_INT32 m_nCountActiveX = 1;
_INT32 m_nThemeOverrideCount = 1;
BinDocxRW::CDocxSerializer* m_pMainDocument = NULL;
BinDocxRW::CDocxSerializer* m_pMainDocument;
int m_nDocumentType;
CBinaryFileReader();

View File

@ -238,8 +238,7 @@ namespace BinXlsxRW
ExternalLinksAutoRefresh = 26,
TimelineCaches = 27,
TimelineCache = 28,
Metadata = 29,
XmlMap = 30
Metadata = 29
};}
namespace c_oSerWorkbookProtection {enum c_oSerWorkbookProtection{
AlgorithmName = 0,
@ -457,7 +456,7 @@ namespace BinXlsxRW
TimelinesList = 48,
Timelines = 49,
Timeline = 50,
TableSingleCells = 51
};}
namespace c_oSerWorksheetProtection {enum c_oSerWorksheetPropTypes
{
@ -1114,12 +1113,7 @@ namespace BinXlsxRW
QueryTableFieldId = 11,
TotalsRowCellStyle = 12,
TotalsRowDxfId = 13,
UniqueName = 14,
XmlColumnPr = 15,
MapId = 16,
Xpath = 17,
Denormalized = 18,
XmlDataType = 19
UniqueName = 14
};}
namespace c_oSer_SortState{enum c_oSer_SortState
{

View File

@ -71,8 +71,6 @@
#include "../../../XlsxFormat/Styles/TableStyles.h"
#include "../../../XlsxFormat/Timelines/Timeline.h"
#include "../../../XlsxFormat/Workbook/Metadata.h"
#include "../../../XlsxFormat/Table/Table.h"
#include "../../../XlsxFormat/Workbook/CustomsXml.h"
#include "../../../../DesktopEditor/common/Directory.h"
#include "../../../../Common/OfficeFileFormatChecker.h"
@ -992,12 +990,6 @@ void BinaryTableWriter::WriteTableColumn(const OOX::Spreadsheet::CTableColumn& o
m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::UniqueName);
m_oBcw.m_oStream.WriteStringW(*oTableColumn.m_oUniqueName);
}
if (oTableColumn.m_oXmlColumnPr.IsInit())
{
nCurPos = m_oBcw.WriteItemStart(c_oSer_TableColumns::XmlColumnPr);
WriteTableXmlColumnPr(oTableColumn.m_oXmlColumnPr.get());
m_oBcw.WriteItemEnd(nCurPos);
}
}
void BinaryTableWriter::WriteTableColumns(const OOX::Spreadsheet::CTableColumns& oTableColumns)
{
@ -1009,43 +1001,15 @@ void BinaryTableWriter::WriteTableColumns(const OOX::Spreadsheet::CTableColumns&
m_oBcw.WriteItemEnd(nCurPos);
}
}
void BinaryTableWriter::WriteTableXmlColumnPr(const OOX::Spreadsheet::CXmlColumnPr & oXmlColumnPr)
{
if (oXmlColumnPr.mapId.IsInit())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::MapId);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long);
m_oBcw.m_oStream.WriteLONG(*oXmlColumnPr.mapId);
}
if (oXmlColumnPr.xpath.IsInit())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::Xpath);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable);
m_oBcw.m_oStream.WriteStringW(*oXmlColumnPr.xpath);
}
if (oXmlColumnPr.denormalized.IsInit())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::Denormalized);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBOOL(*oXmlColumnPr.denormalized);
}
if (oXmlColumnPr.xmlDataType.IsInit())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::XmlDataType);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(oXmlColumnPr.xmlDataType->GetValue());
}
}
void BinaryTableWriter::WriteTableStyleInfo(const OOX::Spreadsheet::CTableStyleInfo& oTableStyleInfo)
{
if (oTableStyleInfo.m_oName.IsInit())
if(oTableStyleInfo.m_oName.IsInit())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleInfo::Name);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable);
m_oBcw.m_oStream.WriteStringW(oTableStyleInfo.m_oName.get2());
}
if (oTableStyleInfo.m_oShowColumnStripes.IsInit())
if(oTableStyleInfo.m_oShowColumnStripes.IsInit())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleInfo::ShowColumnStripes);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
@ -2188,7 +2152,7 @@ void BinaryWorkbookTableWriter::WriteWorkbook(OOX::Spreadsheet::CWorkbook& workb
}
if (workbook.m_oPivotCaches.IsInit())
{
nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::PivotCachesTmp);
nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::PivotCaches);
WritePivotCaches(workbook, workbook.m_oPivotCaches.get());
if (workbook.m_oExtLst.IsInit())
{
@ -2326,16 +2290,6 @@ void BinaryWorkbookTableWriter::WriteWorkbook(OOX::Spreadsheet::CWorkbook& workb
WriteMetadata(pMetadataFile->m_oMetadata.GetPointer());
m_oBcw.WriteItemWithLengthEnd(nCurPos);
}
pFile = workbook.Find(OOX::Spreadsheet::FileTypes::XmlMaps);
OOX::Spreadsheet::CXmlMapsFile* pXmlMapFile = dynamic_cast<OOX::Spreadsheet::CXmlMapsFile*>(pFile.GetPointer());
if (pXmlMapFile)
{
nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::XmlMap);
m_oBcw.m_oStream.StartRecord(0);
pXmlMapFile->toPPTY(&m_oBcw.m_oStream);
m_oBcw.m_oStream.EndRecord();
m_oBcw.WriteItemWithLengthEnd(nCurPos);
}
}
void BinaryWorkbookTableWriter::WriteFileSharing(const OOX::Spreadsheet::CFileSharing& fileSharing)
{
@ -2709,9 +2663,6 @@ void BinaryWorkbookTableWriter::WritePivotCache(OOX::Spreadsheet::CWorkbook& wor
{
nCurPos = m_oBcw.WriteItemStart(c_oSer_PivotTypes::cache);
NSStringUtils::CStringBuilder writer;
writer.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
if(pivotCacheFile->m_oPivotCashDefinition->m_oRid.IsInit())
pivotCacheFile->m_oPivotCashDefinition->m_oRid.reset();
pivotCacheFile->m_oPivotCashDefinition->toXML(writer);
auto wstringData = writer.GetData();
m_oBcw.m_oStream.WriteStringUtf8(wstringData);
@ -4818,7 +4769,7 @@ void BinaryWorksheetTableWriter::WriteWorksheet(OOX::Spreadsheet::CSheet* pSheet
if ((pPivotTableFile) && (pPivotTableFile->m_oPivotTableDefinition.IsInit()))
{
BinaryTableWriter oBinaryTableWriter(m_oBcw.m_oStream);
nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::PivotTableTmp);
nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::PivotTable);
if(pPivotTableFile->m_oPivotTableDefinition->m_oCacheId.IsInit())
{
auto cachePos = m_oBcw.WriteItemStart(c_oSer_PivotTypes::cacheId);
@ -4833,16 +4784,6 @@ void BinaryWorksheetTableWriter::WriteWorksheet(OOX::Spreadsheet::CSheet* pSheet
m_oBcw.WriteItemWithLengthEnd(tablePos);
m_oBcw.WriteItemWithLengthEnd(nCurPos);
}
pFile = oWorksheet.Find(OOX::Spreadsheet::FileTypes::TableSingleCells);
OOX::Spreadsheet::CTableSingleCellsFile* pTableSingleCells = dynamic_cast<OOX::Spreadsheet::CTableSingleCellsFile*>(pFile.GetPointer());
if (pTableSingleCells)
{
nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::TableSingleCells);
m_oBcw.m_oStream.StartRecord(0);
pTableSingleCells->toPPTY(&m_oBcw.m_oStream);
m_oBcw.m_oStream.EndRecord();
m_oBcw.WriteItemWithLengthEnd(nCurPos);
}
}
void BinaryWorksheetTableWriter::WriteWorksheetProp(OOX::Spreadsheet::CSheet& oSheet)
{
@ -5718,21 +5659,6 @@ void BinaryWorksheetTableWriter::WriteSheetData(const OOX::Spreadsheet::CSheetDa
nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Row);
WriteRow(*pRow);
m_oBcw.WriteItemEnd(nCurPos);
if(pRow->m_oRepeated.IsInit())
{
_INT32 rowTimes = pRow->m_oRepeated.get() - 1;
while(rowTimes > 0)
{
if(pRow->m_oR.IsInit())
pRow->m_oR = pRow->m_oR->GetValue() + 1;
if(!pRow->m_arrItems.empty() && pRow->m_arrItems.at(0)->m_oRow.IsInit())
pRow->m_arrItems.at(0)->m_oRow = pRow->m_oR->GetValue();
nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Row);
WriteRow(*pRow);
m_oBcw.WriteItemEnd(nCurPos);
rowTimes--;
}
}
}
}
}
@ -5794,13 +5720,6 @@ void BinaryWorksheetTableWriter::WriteRow(const OOX::Spreadsheet::CRow& oRows)
WriteCells(oRows);
m_oBcw.WriteItemWithLengthEnd(nCurPos);
}
else
{
m_oBcw.m_oStream.WriteBYTE(c_oSerRowTypes::Cells);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable);
nCurPos = m_oBcw.WriteItemWithLengthStart();
m_oBcw.WriteItemWithLengthEnd(nCurPos);
}
}
void BinaryWorksheetTableWriter::WriteCells(const OOX::Spreadsheet::CRow& oRows)
{
@ -5811,25 +5730,6 @@ void BinaryWorksheetTableWriter::WriteCells(const OOX::Spreadsheet::CRow& oRows)
nCurPos = m_oBcw.WriteItemStart(c_oSerRowTypes::Cell);
WriteCell(*oCell);
m_oBcw.WriteItemWithLengthEnd(nCurPos);
if(oCell->m_oRepeated.IsInit())
{
_INT32 cellTimes = oCell->m_oRepeated.get() - 1;
_INT32 originalCol = 0;
if(oCell->m_oCol.IsInit())
originalCol = oCell->m_oCol.get();
while(cellTimes > 0)
{
if(oCell->m_oCol.IsInit())
oCell->m_oCol = oCell->m_oCol.get() + 1;
nCurPos = m_oBcw.WriteItemStart(c_oSerRowTypes::Cell);
WriteCell(*oCell);
m_oBcw.WriteItemWithLengthEnd(nCurPos);
cellTimes--;
}
if(oCell->m_oCol.IsInit())
oCell->m_oCol = originalCol;
}
}
}
void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell)
@ -8884,7 +8784,7 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring
if (fileType == 1)
{
//pXlsx->m_pXlsbWriter = &oXlsbWriter; // todooo xlsb -> xlst without xlsx write folder
pXlsx->m_pXlsbWriter = &oXlsbWriter; // todooo xlsb -> xlst without xlsx write folder
}
//parse
pXlsx->Read(OOX::CPath(sInputDir));

View File

@ -84,7 +84,6 @@ namespace OOX
class CTimelineStyle;
class CTimelineStyles;
class CTimelineStyleElement;
class CXmlColumnPr;
class CMetadata;
class CFutureMetadata;
@ -139,7 +138,6 @@ namespace BinXlsxRW
void WriteQueryTableField(const OOX::Spreadsheet::CQueryTableField& oQueryTableField);
void WriteQueryTableDeletedFields(const OOX::Spreadsheet::CQueryTableDeletedFields& oQueryTableDeletedFields);
void WriteQueryTableDeletedField(const OOX::Spreadsheet::CQueryTableDeletedField& oQueryTableDeletedField);
void WriteTableXmlColumnPr(const OOX::Spreadsheet::CXmlColumnPr & oXmlColumnPr);
};
class BinaryStyleTableWriter
{

Some files were not shown because too many files have changed in this diff Show More