@@ -77,7 +77,7 @@ Painter::Painter(Gfx::Bitmap& bitmap)
77
77
ASSERT (bitmap.physical_height () % scale == 0 );
78
78
m_state_stack.append (State ());
79
79
state ().font = &FontDatabase::default_font ();
80
- state ().clip_rect = { { 0 , 0 }, bitmap.physical_size () };
80
+ state ().clip_rect = { { 0 , 0 }, bitmap.size () };
81
81
state ().scale = scale;
82
82
m_clip_origin = state ().clip_rect ;
83
83
}
@@ -106,11 +106,12 @@ void Painter::fill_rect_with_draw_op(const IntRect& a_rect, Color color)
106
106
107
107
void Painter::clear_rect (const IntRect& a_rect, Color color)
108
108
{
109
- auto rect = to_physical ( a_rect).intersected (clip_rect ());
109
+ auto rect = a_rect. translated ( translation () ).intersected (clip_rect ());
110
110
if (rect.is_empty ())
111
111
return ;
112
112
113
- ASSERT (m_target->physical_rect ().contains (rect));
113
+ ASSERT (m_target->rect ().contains (rect));
114
+ rect *= scale ();
114
115
115
116
RGBA32* dst = m_target->scanline (rect.top ()) + rect.left ();
116
117
const size_t dst_skip = m_target->pitch () / sizeof (RGBA32);
@@ -121,18 +122,14 @@ void Painter::clear_rect(const IntRect& a_rect, Color color)
121
122
}
122
123
}
123
124
124
- void Painter::fill_physical_rect (const IntRect& a_physical_rect , Color color)
125
+ void Painter::fill_physical_rect (const IntRect& physical_rect , Color color)
125
126
{
126
- auto rect = a_physical_rect.intersected (clip_rect ());
127
- if (rect.is_empty ())
128
- return ;
129
- ASSERT (m_target->physical_rect ().contains (rect));
130
-
131
- RGBA32* dst = m_target->scanline (rect.top ()) + rect.left ();
127
+ // Callers must do clipping.
128
+ RGBA32* dst = m_target->scanline (physical_rect.top ()) + physical_rect.left ();
132
129
const size_t dst_skip = m_target->pitch () / sizeof (RGBA32);
133
130
134
- for (int i = rect .height () - 1 ; i >= 0 ; --i) {
135
- for (int j = 0 ; j < rect .width (); ++j)
131
+ for (int i = physical_rect .height () - 1 ; i >= 0 ; --i) {
132
+ for (int j = 0 ; j < physical_rect .width (); ++j)
136
133
dst[j] = Color::from_rgba (dst[j]).blend (color).value ();
137
134
dst += dst_skip;
138
135
}
@@ -153,7 +150,12 @@ void Painter::fill_rect(const IntRect& a_rect, Color color)
153
150
return ;
154
151
}
155
152
156
- fill_physical_rect (to_physical (a_rect), color);
153
+ auto rect = a_rect.translated (translation ()).intersected (clip_rect ());
154
+ if (rect.is_empty ())
155
+ return ;
156
+ ASSERT (m_target->rect ().contains (rect));
157
+
158
+ fill_physical_rect (rect * scale (), color);
157
159
}
158
160
159
161
void Painter::fill_rect_with_dither_pattern (const IntRect& a_rect, Color color_a, Color color_b)
@@ -209,7 +211,7 @@ void Painter::fill_rect_with_gradient(Orientation orientation, const IntRect& a_
209
211
#endif
210
212
211
213
auto rect = to_physical (a_rect);
212
- auto clipped_rect = IntRect::intersection (rect, clip_rect ());
214
+ auto clipped_rect = IntRect::intersection (rect, clip_rect () * scale () );
213
215
if (clipped_rect.is_empty ())
214
216
return ;
215
217
@@ -323,58 +325,51 @@ void Painter::draw_focus_rect(const IntRect& rect, Color color)
323
325
324
326
void Painter::draw_rect (const IntRect& a_rect, Color color, bool rough)
325
327
{
326
- IntRect rect = to_physical ( a_rect);
328
+ IntRect rect = a_rect. translated ( translation () );
327
329
auto clipped_rect = rect.intersected (clip_rect ());
328
330
if (clipped_rect.is_empty ())
329
331
return ;
330
332
331
333
int min_y = clipped_rect.top ();
332
334
int max_y = clipped_rect.bottom ();
333
-
334
- // Don't use rect.bottom() / right() when dealing with physical rects: They will be off by scale()-1 physical pixels.
335
- // (It's fine to use them when comparing bottom() / right() to other physical rects, since then both rects are off by the same amount.
336
- // But don't use them for pixel access.)
337
- int max_y_rounded_to_logical_increment = clipped_rect.top () + clipped_rect.height () - scale ();
338
- int max_x_rounded_to_logical_increment = clipped_rect.left () + clipped_rect.width () - scale ();
335
+ int scale = this ->scale ();
339
336
340
337
if (rect.top () >= clipped_rect.top () && rect.top () <= clipped_rect.bottom ()) {
341
- int start_x = rough ? max (rect.x () + scale (), clipped_rect.x ()) : clipped_rect.x ();
342
- int width = rough ? min (rect.width () - 2 * scale (), clipped_rect.width ()) : clipped_rect.width ();
343
- for (int i = 0 ; i < scale (); ++i) {
344
- fill_physical_scanline_with_draw_op (rect.top () + i, start_x, width, color);
345
- ++min_y;
346
- }
338
+ int start_x = rough ? max (rect.x () + 1 , clipped_rect.x ()) : clipped_rect.x ();
339
+ int width = rough ? min (rect.width () - 2 , clipped_rect.width ()) : clipped_rect.width ();
340
+ for (int i = 0 ; i < scale; ++i)
341
+ fill_physical_scanline_with_draw_op (rect.top () * scale + i, start_x * scale, width * scale, color);
342
+ ++min_y;
347
343
}
348
344
if (rect.bottom () >= clipped_rect.top () && rect.bottom () <= clipped_rect.bottom ()) {
349
- int start_x = rough ? max (rect.x () + scale (), clipped_rect.x ()) : clipped_rect.x ();
350
- int width = rough ? min (rect.width () - 2 * scale (), clipped_rect.width ()) : clipped_rect.width ();
351
- for (int i = 0 ; i < scale (); ++i) {
352
- fill_physical_scanline_with_draw_op (max_y_rounded_to_logical_increment + i, start_x, width, color);
353
- --max_y;
354
- }
345
+ int start_x = rough ? max (rect.x () + 1 , clipped_rect.x ()) : clipped_rect.x ();
346
+ int width = rough ? min (rect.width () - 2 , clipped_rect.width ()) : clipped_rect.width ();
347
+ for (int i = 0 ; i < scale; ++i)
348
+ fill_physical_scanline_with_draw_op (max_y * scale + i, start_x * scale, width * scale, color);
349
+ --max_y;
355
350
}
356
351
357
352
bool draw_left_side = rect.left () >= clipped_rect.left ();
358
353
bool draw_right_side = rect.right () == clipped_rect.right ();
359
354
360
355
if (draw_left_side && draw_right_side) {
361
356
// Specialized loop when drawing both sides.
362
- for (int y = min_y; y <= max_y; ++y) {
357
+ for (int y = min_y * scale ; y <= max_y * scale ; ++y) {
363
358
auto * bits = m_target->scanline (y);
364
- for (int i = 0 ; i < scale () ; ++i)
365
- set_physical_pixel_with_draw_op (bits[rect.left () + i], color);
366
- for (int i = 0 ; i < scale () ; ++i)
367
- set_physical_pixel_with_draw_op (bits[max_x_rounded_to_logical_increment + i], color);
359
+ for (int i = 0 ; i < scale; ++i)
360
+ set_physical_pixel_with_draw_op (bits[rect.left () * scale + i], color);
361
+ for (int i = 0 ; i < scale; ++i)
362
+ set_physical_pixel_with_draw_op (bits[rect. right () * scale + i], color);
368
363
}
369
364
} else {
370
- for (int y = min_y; y <= max_y; ++y) {
365
+ for (int y = min_y * scale ; y <= max_y * scale ; ++y) {
371
366
auto * bits = m_target->scanline (y);
372
367
if (draw_left_side)
373
- for (int i = 0 ; i < scale () ; ++i)
374
- set_physical_pixel_with_draw_op (bits[rect.left () + i], color);
368
+ for (int i = 0 ; i < scale; ++i)
369
+ set_physical_pixel_with_draw_op (bits[rect.left () * scale + i], color);
375
370
if (draw_right_side)
376
- for (int i = 0 ; i < scale () ; ++i)
377
- set_physical_pixel_with_draw_op (bits[max_x_rounded_to_logical_increment + i], color);
371
+ for (int i = 0 ; i < scale; ++i)
372
+ set_physical_pixel_with_draw_op (bits[rect. right () * scale + i], color);
378
373
}
379
374
}
380
375
}
@@ -409,18 +404,20 @@ void Painter::draw_bitmap(const IntPoint& p, const CharacterBitmap& bitmap, Colo
409
404
410
405
void Painter::draw_bitmap (const IntPoint& p, const GlyphBitmap& bitmap, Color color)
411
406
{
412
- auto dst_rect = to_physical ( IntRect (p, bitmap.size ()));
407
+ auto dst_rect = IntRect (p, bitmap.size ()). translated ( translation ( ));
413
408
auto clipped_rect = dst_rect.intersected (clip_rect ());
414
409
if (clipped_rect.is_empty ())
415
410
return ;
416
411
const int first_row = clipped_rect.top () - dst_rect.top ();
417
412
const int last_row = clipped_rect.bottom () - dst_rect.top ();
418
413
const int first_column = clipped_rect.left () - dst_rect.left ();
419
414
const int last_column = clipped_rect.right () - dst_rect.left ();
420
- RGBA32* dst = m_target->scanline (clipped_rect.y ()) + clipped_rect.x ();
415
+
416
+ int scale = this ->scale ();
417
+ RGBA32* dst = m_target->scanline (clipped_rect.y () * scale) + clipped_rect.x () * scale;
421
418
const size_t dst_skip = m_target->pitch () / sizeof (RGBA32);
422
419
423
- if (scale () == 1 ) {
420
+ if (scale == 1 ) {
424
421
for (int row = first_row; row <= last_row; ++row) {
425
422
for (int j = 0 ; j <= (last_column - first_column); ++j) {
426
423
if (bitmap.bit_at (j + first_column, row))
@@ -431,10 +428,13 @@ void Painter::draw_bitmap(const IntPoint& p, const GlyphBitmap& bitmap, Color co
431
428
} else {
432
429
for (int row = first_row; row <= last_row; ++row) {
433
430
for (int j = 0 ; j <= (last_column - first_column); ++j) {
434
- if (bitmap.bit_at ((j + first_column) / scale (), row / scale ()))
435
- dst[j] = color.value ();
431
+ if (bitmap.bit_at ((j + first_column), row)) {
432
+ for (int iy = 0 ; iy < scale; ++iy)
433
+ for (int ix = 0 ; ix < scale; ++ix)
434
+ dst[j * scale + ix + iy * dst_skip] = color.value ();
435
+ }
436
436
}
437
- dst += dst_skip;
437
+ dst += dst_skip * scale ;
438
438
}
439
439
}
440
440
}
@@ -701,16 +701,22 @@ void Painter::blit_with_alpha(const IntPoint& position, const Gfx::Bitmap& sourc
701
701
702
702
ASSERT (source.has_alpha_channel ());
703
703
IntRect safe_src_rect = a_src_rect.intersected (source.rect ());
704
- auto dst_rect = to_physical (IntRect (position, safe_src_rect.size ()));
705
- auto src_rect = a_src_rect * source.scale ();
704
+ auto dst_rect = IntRect (position, safe_src_rect.size ()).translated (translation ());
706
705
707
706
auto clipped_rect = dst_rect.intersected (clip_rect ());
708
707
if (clipped_rect.is_empty ())
709
708
return ;
709
+
710
+ int scale = this ->scale ();
711
+ auto src_rect = a_src_rect * scale;
712
+ clipped_rect *= scale;
713
+ dst_rect *= scale;
714
+
710
715
const int first_row = clipped_rect.top () - dst_rect.top ();
711
716
const int last_row = clipped_rect.bottom () - dst_rect.top ();
712
717
const int first_column = clipped_rect.left () - dst_rect.left ();
713
718
const int last_column = clipped_rect.right () - dst_rect.left ();
719
+
714
720
RGBA32* dst = m_target->scanline (clipped_rect.y ()) + clipped_rect.x ();
715
721
const RGBA32* src = source.scanline (src_rect.top () + first_row) + src_rect.left () + first_column;
716
722
const size_t dst_skip = m_target->pitch () / sizeof (RGBA32);
@@ -744,15 +750,19 @@ void Painter::blit(const IntPoint& position, const Gfx::Bitmap& source, const In
744
750
745
751
// If we get here, the Painter might have a scale factor, but the source bitmap has the same scale factor.
746
752
// We need to transform from logical to physical coordinates, but we can just copy pixels without resampling.
747
- // All computations below are in physical coordinates (except for safe_src_rect).
748
753
auto safe_src_rect = a_src_rect.intersected (source.rect ());
749
754
ASSERT (source.rect ().contains (safe_src_rect));
750
- auto dst_rect = to_physical (IntRect (position, safe_src_rect.size ()));
751
- auto src_rect = a_src_rect * source.scale ();
752
-
755
+ auto dst_rect = IntRect (position, safe_src_rect.size ()).translated (translation ());
753
756
auto clipped_rect = dst_rect.intersected (clip_rect ());
754
757
if (clipped_rect.is_empty ())
755
758
return ;
759
+
760
+ // All computations below are in physical coordinates.
761
+ int scale = this ->scale ();
762
+ auto src_rect = a_src_rect * scale;
763
+ clipped_rect *= scale;
764
+ dst_rect *= scale;
765
+
756
766
const int first_row = clipped_rect.top () - dst_rect.top ();
757
767
const int last_row = clipped_rect.bottom () - dst_rect.top ();
758
768
const int first_column = clipped_rect.left () - dst_rect.left ();
@@ -849,8 +859,7 @@ void Painter::draw_scaled_bitmap(const IntRect& a_dst_rect, const Gfx::Bitmap& s
849
859
850
860
auto dst_rect = to_physical (a_dst_rect);
851
861
auto src_rect = a_src_rect * source.scale ();
852
-
853
- auto clipped_rect = dst_rect.intersected (clip_rect ());
862
+ auto clipped_rect = dst_rect.intersected (clip_rect () * scale ());
854
863
if (clipped_rect.is_empty ())
855
864
return ;
856
865
@@ -1261,7 +1270,7 @@ void Painter::draw_line(const IntPoint& p1, const IntPoint& p2, Color color, int
1261
1270
if (color.alpha () == 0 )
1262
1271
return ;
1263
1272
1264
- auto clip_rect = this ->clip_rect ();
1273
+ auto clip_rect = this ->clip_rect () * scale () ;
1265
1274
1266
1275
auto point1 = to_physical (p1);
1267
1276
auto point2 = to_physical (p2);
@@ -1495,8 +1504,8 @@ void Painter::draw_elliptical_arc(const IntPoint& p1, const IntPoint& p2, const
1495
1504
1496
1505
void Painter::add_clip_rect (const IntRect& rect)
1497
1506
{
1498
- state ().clip_rect .intersect (to_physical ( rect));
1499
- state ().clip_rect .intersect (m_target->physical_rect ()); // FIXME: This shouldn't be necessary?
1507
+ state ().clip_rect .intersect (rect. translated ( translation () ));
1508
+ state ().clip_rect .intersect (m_target->rect ()); // FIXME: This shouldn't be necessary?
1500
1509
}
1501
1510
1502
1511
void Painter::clear_clip_rect ()
0 commit comments