Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit dd859c6

Browse files
Merge pull request #6263 from runrevmark/svg-revision_3
[[ SVG ]] Revision 3
2 parents 141e7f4 + 4201052 commit dd859c6

File tree

13 files changed

+639
-1018
lines changed

13 files changed

+639
-1018
lines changed

engine/src/graphicscontext.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,10 +1232,6 @@ void MCGraphicsContext::fillpath(MCPath *path, bool p_evenodd)
12321232

12331233
void MCGraphicsContext::drawpict(uint1 *data, uint4 length, bool embed, const MCRectangle& drect, const MCRectangle& crect)
12341234
{
1235-
MCGContextSave(m_gcontext);
1236-
MCGContextClipToRect(m_gcontext, MCRectangleToMCGRectangle(crect));
1237-
MCGContextPlayback(m_gcontext, MCRectangleToMCGRectangle(drect), MCMakeSpan(static_cast<const byte_t*>(data), length));
1238-
MCGContextRestore(m_gcontext);
12391235
}
12401236

12411237
void MCGraphicsContext::draweps(real8 sx, real8 sy, int2 angle, real8 xscale, real8 yscale, int2 tx, int2 ty,

engine/src/idraw.cpp

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,71 @@ bool MCImage::get_rep_and_transform(MCImageRep *&r_rep, bool &r_has_transform, M
8080

8181
void MCImage::drawme(MCDC *dc, int2 sx, int2 sy, uint2 sw, uint2 sh, int2 dx, int2 dy, uint2 dw, uint2 dh)
8282
{
83-
MCRectangle drect, crect;
84-
8583
if (m_rep != nil)
8684
{
85+
/* Printer output generally requires special-casing */
86+
bool t_printer = dc->gettype() == CONTEXT_TYPE_PRINTER;
87+
88+
/* Update the transform - as necessary */
89+
bool t_update = !((state & CS_SIZE) && (state & CS_EDITED));
90+
91+
if (t_update)
92+
apply_transform();
93+
8794
if (m_rep->GetType() == kMCImageRepVector)
8895
{
89-
MCU_set_rect(drect, dx - sx, dy - sy, rect.width, rect.height);
90-
MCU_set_rect(crect, dx, dy, dw, dh);
91-
static_cast<MCVectorImageRep*>(m_rep)->Render(dc, false, drect, crect);
96+
MCGAffineTransform t_transform;
97+
if (m_has_transform)
98+
{
99+
t_transform = m_transform;
100+
}
101+
else
102+
{
103+
t_transform = MCGAffineTransformMakeIdentity();
104+
}
105+
106+
uindex_t t_rep_width, t_rep_height;
107+
m_rep->GetGeometry(t_rep_width, t_rep_height);
108+
109+
// MW-2014-06-19: [[ IconGravity ]] Scale the image appropriately.
110+
if (dw != sw || dh != sh)
111+
{
112+
t_transform = MCGAffineTransformPreScale(t_transform, dw / (float)sw, dh / (float)sh);
113+
}
114+
115+
// MW-2014-06-19: [[ IconGravity ]] Only clip if we are drawing a partial image (we need to double-check, but I don't think sx/sy are ever non-zero).
116+
MCRectangle t_old_clip;
117+
t_old_clip = dc->getclip();
118+
if (sx != 0 && sy != 0)
119+
{
120+
dc->setclip(MCRectangleMake(dx, dy, sw, sh));
121+
}
122+
123+
t_transform = MCGAffineTransformConcat(t_transform,
124+
MCGAffineTransformMakeTranslation(-(dx - sx), -(dy - sy)));
125+
t_transform = MCGAffineTransformPreTranslate(t_transform, (dx - sx), (dy - sy));
126+
127+
MCGContextRef t_gcontext;
128+
if (dc->lockgcontext(t_gcontext))
129+
{
130+
MCGContextSave(t_gcontext);
131+
132+
MCGContextConcatCTM(t_gcontext, t_transform);
133+
134+
auto t_vector_rep = static_cast<MCVectorImageRep *>(m_rep);
135+
136+
void* t_data;
137+
uindex_t t_data_size;
138+
t_vector_rep->GetData(t_data, t_data_size);
139+
140+
MCGContextPlaybackRectOfDrawing(t_gcontext, MCMakeSpan((const byte_t*)t_data, t_data_size), MCGRectangleMake(0, 0, t_rep_width, t_rep_height), MCGRectangleMake(dx - sx, dy - sy, t_rep_width, t_rep_height));
141+
142+
MCGContextRestore(t_gcontext);
143+
144+
dc->unlockgcontext(t_gcontext);
145+
}
146+
147+
dc->setclip(t_old_clip);
92148
}
93149
else
94150
{
@@ -99,12 +155,6 @@ void MCImage::drawme(MCDC *dc, int2 sx, int2 sy, uint2 sw, uint2 sh, int2 dx, in
99155
bool t_success = true;
100156

101157
MCGImageFrame t_frame;
102-
103-
bool t_printer = dc->gettype() == CONTEXT_TYPE_PRINTER;
104-
bool t_update = !((state & CS_SIZE) && (state & CS_EDITED));
105-
106-
if (t_update)
107-
apply_transform();
108158

109159
// IM-2013-11-06: [[ RefactorGraphics ]] Use common method to get image rep & transform
110160
// so imagedata & rendered image have the same appearance
@@ -201,7 +251,7 @@ void MCImage::drawme(MCDC *dc, int2 sx, int2 sy, uint2 sw, uint2 sh, int2 dx, in
201251
else
202252
{
203253
// can't get image data from rep
204-
drawnodata(dc, drect, sw, sh, dx, dy, dw, dh);
254+
drawnodata(dc, sw, sh, dx, dy, dw, dh);
205255
}
206256

207257
if (t_success)
@@ -233,12 +283,13 @@ void MCImage::drawme(MCDC *dc, int2 sx, int2 sy, uint2 sw, uint2 sh, int2 dx, in
233283
else if (!MCStringIsEmpty(filename))
234284
{
235285
// AL-2014-01-15: [[ Bug 11570 ]] Draw stippled background when referenced image file not found
236-
drawnodata(dc, rect, sw, sh, dx, dy, dw, dh);
286+
drawnodata(dc, sw, sh, dx, dy, dw, dh);
237287
}
238288
}
239289

240-
void MCImage::drawnodata(MCDC *dc, MCRectangle drect, uint2 sw, uint2 sh, int2 dx, int2 dy, uint2 dw, uint2 dh)
290+
void MCImage::drawnodata(MCDC *dc, uint2 sw, uint2 sh, int2 dx, int2 dy, uint2 dw, uint2 dh)
241291
{
292+
MCRectangle drect;
242293
MCU_set_rect(drect, dx, dy, dw, dh);
243294
setforeground(dc, DI_BACK, False);
244295
dc->setbackground(MCscreen->getwhite());

engine/src/iimport.cpp

Lines changed: 25 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -56,145 +56,41 @@ bool read_all(IO_handle p_stream, uint8_t *&r_data, uindex_t &r_data_size)
5656
return t_success;
5757
}
5858

59-
#define META_HEAD_SIZE 44
60-
#define EMF_HEAD_SIZE 80
59+
#define DRAWING_HEAD_SIZE 12
6160
bool MCImageGetMetafileGeometry(IO_handle p_stream, uindex_t &r_width, uindex_t &r_height)
6261
{
6362
bool t_success = true;
6463
bool t_is_meta = false;
6564

6665
uindex_t t_stream_pos = MCS_tell(p_stream);
67-
uint8_t t_head[EMF_HEAD_SIZE];
68-
uindex_t t_size = META_HEAD_SIZE;
66+
uint8_t t_head[DRAWING_HEAD_SIZE];
67+
uindex_t t_size = DRAWING_HEAD_SIZE;
6968

7069
t_success = IO_NORMAL == MCS_readfixed(t_head, t_size, p_stream) &&
71-
t_size == META_HEAD_SIZE;
72-
73-
if (t_success)
70+
t_size == DRAWING_HEAD_SIZE;
71+
72+
/* A drawing's header is of the form:
73+
* 0: LCD\0
74+
* 4: width
75+
* 8: height
76+
*/
77+
if (t_success &&
78+
memcmp(t_head, "LCD\0", 4) == 0)
7479
{
75-
if (memcmp(t_head, "LCD\0", 4) == 0)
76-
{
77-
/* A drawing's header is of the form:
78-
* 0: LCD\0
79-
* 4: flags
80-
* bit 0: has width
81-
* bit 1: has height
82-
* bit 2: has viewport
83-
* 8: scalar_count
84-
* 12: width if 'has width'
85-
* 16: height if 'has height'
86-
* 20: viewbox if 'has viewport'.
87-
*
88-
* If a drawing has a width >= 0 then that is its intrinsic width
89-
* Else if it has a viewport then the viewbox width is its intrinsic width
90-
* Else the intrinsic width is unknown
91-
*
92-
* If a drawing has a height >= 0, then that is its intrinsic height
93-
* Else if it has a viewport, then the viewbox height is its intrisic width
94-
* Else the intrisic height is unknown
95-
*
96-
* Currently unknown intrinsic width/height is reported as 256.
97-
*/
98-
uint32_t t_flags = *(uint32_t *)(t_head + 4);
99-
const float *t_scalars = (const float *)(t_head + 12);
100-
float t_width = -1, t_height = -1;
101-
102-
/* Get the width, if the width flag (bit 0) is set. */
103-
if ((t_flags & (1 << 0)) != 0)
104-
{
105-
t_width = *t_scalars++;
106-
}
107-
108-
/* Get the height, if the height flag (bit 1) is set. */
109-
if ((t_flags & (1 << 1)) != 0)
110-
{
111-
t_height = *t_scalars++;
112-
}
113-
114-
/* Get the viewbox width/height, if the viewport flag (bit 2) is set. */
115-
if ((t_flags & (1 << 2)) != 0)
116-
{
117-
auto t_viewbox = reinterpret_cast<const MCGRectangle*>(t_scalars);
118-
119-
if (t_width < 0)
120-
{
121-
t_width = t_viewbox->size.width;
122-
}
123-
if (t_height < 0)
124-
{
125-
t_height = t_viewbox->size.height;
126-
}
127-
}
128-
129-
/* If the width is not absolute still, take a default of 256. */
130-
if (t_width < 0)
131-
{
132-
t_width = 256;
133-
}
134-
135-
/* If the height is not absolute still, take a default of 256. */
136-
if (t_height < 0)
137-
{
138-
t_height = 256;
139-
}
140-
141-
/* The engine deals with integer bounds on sub-pixel co-ords, so
142-
* take the ceiling of the computer (float) width/height. */
143-
r_width = (uindex_t)ceilf(t_width);
144-
r_height = (uindex_t)ceilf(t_height);
145-
146-
t_is_meta = true;
147-
}
148-
// graphics metafile (wmf)
149-
else if (memcmp(t_head, "\xD7\xCD\xC6\x9A", 4) == 0)
150-
{
151-
int16_t *t_bounds = (int16_t *)&t_head[6];
152-
r_width = ((t_bounds[2] - t_bounds[0]) * 72 + t_bounds[4] - 1) / t_bounds[4];
153-
r_height = ((t_bounds[3] - t_bounds[1]) * 72 + t_bounds[4] - 1) / t_bounds[4];
154-
t_is_meta = true;
155-
}
156-
// win32 metafile (emf)
157-
else if (memcmp(&t_head[40], "\x20\x45\x4D\x46", 4) == 0)
158-
{
159-
t_success =
160-
IO_NORMAL == MCS_seek_set(p_stream, t_stream_pos) &&
161-
IO_NORMAL == MCS_readfixed(t_head, EMF_HEAD_SIZE, p_stream);
162-
163-
if (t_success)
164-
{
165-
int32_t *t_bounds;
166-
t_bounds = (int32_t*)&t_head[72];
167-
r_width = t_bounds[0];
168-
r_height = t_bounds[1];
169-
t_is_meta = true;
170-
}
171-
}
172-
else
173-
{
174-
uindex_t t_offset = 0;
175-
if (memcmp(t_head, "\0\0\0\0\0\0\0\0", 8) == 0)
176-
{
177-
t_offset = 512;
178-
t_success =
179-
IO_NORMAL == MCS_seek_set(p_stream, t_stream_pos + t_offset) &&
180-
IO_NORMAL == MCS_readfixed(t_head, META_HEAD_SIZE, p_stream);
181-
}
182-
183-
// PICT file
184-
if (t_success && memcmp(&t_head[10], "\0\021\002\377", 4) == 0)
185-
{
186-
uint16_t *t_bounds = (uint16_t *)t_head;
187-
r_width = swap_uint2(&t_bounds[4]) - swap_uint2(&t_bounds[2]);
188-
r_height = swap_uint2(&t_bounds[3]) - swap_uint2(&t_bounds[1]);
189-
t_is_meta = true;
190-
t_stream_pos += t_offset;
191-
}
192-
}
193-
}
194-
80+
float t_width = *(const float *)(t_head + 4);
81+
float t_height = *(const float *)(t_head + 8);
82+
83+
/* The engine deals with integer bounds on sub-pixel co-ords, so
84+
* take the ceiling of the computer (float) width/height. */
85+
r_width = (uindex_t)ceilf(t_width);
86+
r_height = (uindex_t)ceilf(t_height);
87+
88+
t_is_meta = true;
89+
}
90+
19591
MCS_seek_set(p_stream, t_stream_pos);
196-
197-
return t_success && t_is_meta;
92+
93+
return t_success && t_is_meta;
19894
}
19995

20096
bool MCImageBitmapApplyMask(MCImageBitmap *p_bitmap, MCImageBitmap *p_mask)

engine/src/image.cpp

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1977,6 +1977,63 @@ bool MCImage::lockbitmap(bool p_premultiplied, bool p_update_transform, const MC
19771977
else
19781978
t_size = *p_size;
19791979

1980+
/* Special case vector image reps - as they don't have pixels! */
1981+
if (t_success &&
1982+
t_rep->GetType() == kMCImageRepVector)
1983+
{
1984+
/* Start with the identity transform, if none */
1985+
if (!t_has_transform)
1986+
t_transform = MCGAffineTransformMakeIdentity();
1987+
1988+
/* Scale from the rect size to the requested size. */
1989+
MCGFloat t_x_scale, t_y_scale;
1990+
t_x_scale = (MCGFloat)t_size.width / (MCGFloat)rect.width;
1991+
t_y_scale = (MCGFloat)t_size.height / (MCGFloat)rect.height;
1992+
t_transform = MCGAffineTransformConcat(MCGAffineTransformMakeScale(t_x_scale, t_y_scale), t_transform);
1993+
1994+
MCImageBitmap *t_bitmap = nullptr;
1995+
t_success = MCImageBitmapCreate(t_size.width, t_size.height, t_bitmap);
1996+
1997+
MCGContextRef t_context = nullptr;
1998+
if (t_success)
1999+
{
2000+
MCImageBitmapClear(t_bitmap);
2001+
t_success = MCGContextCreateWithPixels(t_bitmap->width, t_bitmap->height, t_bitmap->stride, t_bitmap->data, true, t_context);
2002+
}
2003+
2004+
if (t_success)
2005+
{
2006+
MCGContextConcatCTM(t_context, t_transform);
2007+
2008+
auto t_vector_rep = static_cast<MCVectorImageRep *>(t_rep);
2009+
2010+
void* t_data;
2011+
uindex_t t_data_size;
2012+
t_vector_rep->GetData(t_data, t_data_size);
2013+
2014+
MCGContextPlaybackRectOfDrawing(t_context, MCMakeSpan((const byte_t*)t_data, t_data_size), MCGRectangleMake(0, 0, t_width, t_height), MCGRectangleMake(0, 0, t_size.width, t_size.height));
2015+
}
2016+
2017+
MCGContextRelease(t_context);
2018+
2019+
if (t_success)
2020+
{
2021+
MCImageBitmapCheckTransparency(t_bitmap);
2022+
if (!p_premultiplied)
2023+
{
2024+
MCImageBitmapUnpremultiply(t_bitmap);
2025+
}
2026+
2027+
r_bitmap = t_bitmap;
2028+
}
2029+
else
2030+
{
2031+
MCImageFreeBitmap(t_bitmap);
2032+
}
2033+
2034+
return t_success;
2035+
}
2036+
19802037
if (t_success)
19812038
{
19822039
if (!t_has_transform)
@@ -1986,7 +2043,6 @@ bool MCImage::lockbitmap(bool p_premultiplied, bool p_update_transform, const MC
19862043
MCGFloat t_x_scale, t_y_scale;
19872044
t_x_scale = (MCGFloat)t_size.width / (MCGFloat)rect.width;
19882045
t_y_scale = (MCGFloat)t_size.height / (MCGFloat)rect.height;
1989-
19902046
t_transform = MCGAffineTransformConcat(MCGAffineTransformMakeScale(t_x_scale, t_y_scale), t_transform);
19912047

19922048
t_transform_scale = MCGAffineTransformGetEffectiveScale(t_transform);

engine/src/image.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ class MCImage : public MCControl, public MCMixinObjectHandle<MCImage>
518518
// in idraw.cc
519519
void drawme(MCDC *dc, int2 sx, int2 sy, uint2 sw, uint2 sh, int2 dx, int2 dy, uint2 dw, uint2 dh);
520520
void drawcentered(MCDC *dc, int2 x, int2 y, Boolean reverse);
521-
void drawnodata(MCDC *dc, MCRectangle drect, uint2 sw, uint2 sh, int2 dx, int2 dy, uint2 dw, uint2 dh);
521+
void drawnodata(MCDC *dc, uint2 sw, uint2 sh, int2 dx, int2 dy, uint2 dw, uint2 dh);
522522

523523
void drawwithgravity(MCDC *dc, MCRectangle rect, MCGravity gravity);
524524

0 commit comments

Comments
 (0)