Skip to content

Commit a700bd1

Browse files
authored
fix: some more memory leaks (#40)
1 parent dc6dcc0 commit a700bd1

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

native/src/context2d.cpp

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,28 @@
77

88
extern sk_sp<skia::textlayout::FontCollection> fontCollection;
99

10+
void free_style(Style* style) {
11+
if (style->shader != nullptr) {
12+
style->shader.~sk_sp();
13+
}
14+
}
15+
16+
void free_font(Font* font) {
17+
free(font->family);
18+
free(font);
19+
}
20+
21+
Style clone_style(Style* style) {
22+
Style new_style;
23+
new_style.type = style->type;
24+
if (style->type == kStyleColor) {
25+
new_style.color = style->color;
26+
} else if (style->type == kStyleShader) {
27+
new_style.shader = sk_sp(style->shader);
28+
}
29+
return new_style;
30+
}
31+
1032
sk_context_state* create_default_state() {
1133
sk_context_state* state = new sk_context_state();
1234
state->paint = new SkPaint();
@@ -53,10 +75,8 @@ sk_context_state* clone_context_state(sk_context_state* state) {
5375
new_state->lineDash = state->lineDash;
5476
new_state->globalAlpha = state->globalAlpha;
5577
new_state->lineDashOffset = state->lineDashOffset;
56-
new_state->fillStyle = state->fillStyle;
57-
if (new_state->fillStyle.shader) new_state->fillStyle.shader = sk_sp(new_state->fillStyle.shader);
58-
new_state->strokeStyle = state->strokeStyle;
59-
if (new_state->strokeStyle.shader) new_state->strokeStyle.shader = sk_sp(new_state->strokeStyle.shader);
78+
new_state->fillStyle = clone_style(&state->fillStyle);
79+
new_state->strokeStyle = clone_style(&state->strokeStyle);
6080
new_state->shadowColor = state->shadowColor;
6181
new_state->transform = new SkMatrix(*state->transform);
6282
new_state->imageSmoothingEnabled = state->imageSmoothingEnabled;
@@ -78,12 +98,12 @@ sk_context_state* clone_context_state(sk_context_state* state) {
7898
}
7999

80100
void free_context_state(sk_context_state* state) {
81-
if (state->fillStyle.shader) state->fillStyle.shader.~sk_sp();
82-
if (state->strokeStyle.shader) state->strokeStyle.shader.~sk_sp();
101+
free_style(&state->fillStyle);
102+
free_style(&state->strokeStyle);
83103
if (state->filter.get() != nullptr) state->filter.~sk_sp();
84104
delete state->paint;
85105
delete state->transform;
86-
free(state->font);
106+
free_font(state->font);
87107
}
88108

89109
// Utility
@@ -215,6 +235,7 @@ void applyShadowOffsetMatrix(sk_context* context) {
215235
shadowOffset->preTranslate(shadowOffsetX, shadowOffsetY);
216236
canvas->concat(*shadowOffset);
217237
canvas->concat(cts);
238+
delete shadowOffset;
218239
}
219240

220241
extern "C" {
@@ -242,8 +263,10 @@ extern "C" {
242263
applyShadowOffsetMatrix(context);
243264
canvas->drawRect(rect, *shadowPaint);
244265
canvas->restore();
266+
delete shadowPaint;
245267
}
246268
canvas->drawRect(rect, *fillPaint);
269+
delete fillPaint;
247270
}
248271

249272
// Context.strokeRect()
@@ -257,8 +280,10 @@ extern "C" {
257280
applyShadowOffsetMatrix(context);
258281
canvas->drawRect(rect, *shadowPaint);
259282
canvas->restore();
283+
delete shadowPaint;
260284
}
261285
canvas->drawRect(rect, *strokePaint);
286+
delete strokePaint;
262287
}
263288

264289
/// Drawing text
@@ -446,10 +471,11 @@ extern "C" {
446471
shadowPaint
447472
);
448473
context->canvas->restore();
474+
delete shadowPaint;
449475
if (res == 0) return 0;
450476
}
451477
}
452-
return sk_context_text_base(
478+
auto res = sk_context_text_base(
453479
context,
454480
text,
455481
textLen,
@@ -460,6 +486,8 @@ extern "C" {
460486
out_metrics,
461487
paint
462488
);
489+
delete paint;
490+
return res;
463491
}
464492

465493
// Context.fillText() implementation in JS using sk_context_test
@@ -575,7 +603,7 @@ extern "C" {
575603
int variant,
576604
int stretch
577605
) {
578-
free(context->state->font);
606+
free_font(context->state->font);
579607
context->state->font = new Font();
580608
context->state->font->family = strdup(family);
581609
context->state->font->size = size;
@@ -657,6 +685,7 @@ extern "C" {
657685
int sk_context_set_fill_style(sk_context* context, char* style) {
658686
auto color = CSSColorParser::parse(std::string(style));
659687
if (color) {
688+
free_style(&context->state->fillStyle);
660689
auto val = color.value();
661690
context->state->fillStyle = Style();
662691
context->state->fillStyle.type = kStyleColor;
@@ -667,12 +696,14 @@ extern "C" {
667696
}
668697

669698
void sk_context_set_fill_style_gradient(sk_context* context, sk_gradient* gradient) {
699+
free_style(&context->state->fillStyle);
670700
context->state->fillStyle = Style();
671701
context->state->fillStyle.type = kStyleShader;
672702
context->state->fillStyle.shader = sk_gradient_to_shader(gradient, context->state->transform);
673703
}
674704

675705
void sk_context_set_fill_style_pattern(sk_context* context, sk_pattern* pattern) {
706+
free_style(&context->state->fillStyle);
676707
context->state->fillStyle = Style();
677708
context->state->fillStyle.type = kStyleShader;
678709
context->state->fillStyle.shader = sk_pattern_to_shader(pattern);
@@ -684,6 +715,7 @@ extern "C" {
684715
int sk_context_set_stroke_style(sk_context* context, char* style) {
685716
auto color = CSSColorParser::parse(std::string(style));
686717
if (color) {
718+
free_style(&context->state->strokeStyle);
687719
auto val = color.value();
688720
context->state->strokeStyle = Style();
689721
context->state->strokeStyle.type = kStyleColor;
@@ -694,12 +726,14 @@ extern "C" {
694726
}
695727

696728
void sk_context_set_stroke_style_gradient(sk_context* context, sk_gradient* gradient) {
729+
free_style(&context->state->strokeStyle);
697730
context->state->strokeStyle = Style();
698731
context->state->strokeStyle.type = kStyleShader;
699732
context->state->strokeStyle.shader = sk_gradient_to_shader(gradient, context->state->transform);
700733
}
701734

702735
void sk_context_set_stroke_style_pattern(sk_context* context, sk_pattern* pattern) {
736+
free_style(&context->state->strokeStyle);
703737
context->state->strokeStyle = Style();
704738
context->state->strokeStyle.type = kStyleShader;
705739
context->state->strokeStyle.shader = sk_pattern_to_shader(pattern);
@@ -831,8 +865,10 @@ extern "C" {
831865
applyShadowOffsetMatrix(context);
832866
canvas->drawPath(*path, *shadowPaint);
833867
canvas->restore();
868+
delete shadowPaint;
834869
}
835870
canvas->drawPath(*path, *paint);
871+
delete paint;
836872
}
837873

838874
// Context.stroke()
@@ -846,8 +882,10 @@ extern "C" {
846882
applyShadowOffsetMatrix(context);
847883
canvas->drawPath(*path, *shadowPaint);
848884
canvas->restore();
885+
delete shadowPaint;
849886
}
850887
canvas->drawPath(*path, *strokePaint);
888+
delete strokePaint;
851889
}
852890

853891
// TODO?: Context.drawFocusIfNeeded() (should we support it?)
@@ -1080,6 +1118,7 @@ extern "C" {
10801118
shadowPaint,
10811119
SkCanvas::kFast_SrcRectConstraint
10821120
);
1121+
delete shadowPaint;
10831122
}
10841123

10851124
context->canvas->drawImageRect(

0 commit comments

Comments
 (0)