forked from EasyRPG/Player
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbitmap.h
696 lines (616 loc) · 18.7 KB
/
bitmap.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
/*
* This file is part of EasyRPG Player.
*
* EasyRPG Player is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EasyRPG Player is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EP_BITMAP_H
#define EP_BITMAP_H
// Headers
#include <cstdint>
#include <string>
#include <map>
#include <vector>
#include <cassert>
#include <pixman.h>
#include "system.h"
#include "color.h"
#include "rect.h"
#include "pixel_format.h"
#include "tone.h"
#include "text.h"
#include "pixman_image_ptr.h"
#include "opacity.h"
#include "filesystem_stream.h"
#include "string_view.h"
struct Transform;
/**
* Base Bitmap class.
*/
class Bitmap {
public:
/**
* Creates bitmap with empty surface.
*
* @param width surface width.
* @param height surface height.
* @param color color for filling.
*/
static BitmapRef Create(int width, int height, const Color& color);
/**
* Loads a bitmap from a stream.
*
* @param stream stream to read image from.
* @param transparent allow transparency on bitmap.
* @param flags bitmap flags.
*/
static BitmapRef Create(Filesystem_Stream::InputStream stream, bool transparent = true, uint32_t flags = 0);
/*
* Loads a bitmap from memory.
*
* @param data image data.
* @param bytes size of data.
* @param transparent allow transparency on bitmap.
* @param flags bitmap flags.
*/
static BitmapRef Create(const uint8_t* data, unsigned bytes, bool transparent = true, uint32_t flags = 0);
/**
* Creates a bitmap from another.
*
* @param source source bitmap.
* @param src_rect rect to copy from source bitmap.
* @param transparent allow transparency on bitmap.
*/
static BitmapRef Create(Bitmap const& source, Rect const& src_rect, bool transparent = true);
/**
* Creates a surface.
*
* @param width surface width.
* @param height surface height.
* @param bpp surface bpp.
* @param transparent allow transparency on surface.
*/
static BitmapRef Create(int width, int height, bool transparent = true, int bpp = 0);
/**
* Creates a surface wrapper around existing pixel data.
*
* @param pixels pointer to pixel data.
* @param width surface width.
* @param height surface height.
* @param pitch surface pitch.
* @param format pixel format.
*/
static BitmapRef Create(void *pixels, int width, int height, int pitch, const DynamicFormat& format);
Bitmap(int width, int height, bool transparent);
Bitmap(Filesystem_Stream::InputStream stream, bool transparent, uint32_t flags);
Bitmap(const uint8_t* data, unsigned bytes, bool transparent, uint32_t flags);
Bitmap(Bitmap const& source, Rect const& src_rect, bool transparent);
Bitmap(void *pixels, int width, int height, int pitch, const DynamicFormat& format);
/**
* Gets the bitmap width.
*
* @return the bitmap width.
*/
int GetWidth() const;
/**
* Gets the bitmap height.
*
* @return the bitmap height.
*/
int GetHeight() const;
/**
* Gets bitmap bounds rect.
*
* @return bitmap bounds rect.
*/
Rect GetRect() const;
/**
* Gets how many bytes the bitmap consumes.
*
* @return bitmap size in bytes
*/
size_t GetSize() const;
/**
* Gets if bitmap allows transparency.
*
* @return if bitmap allows transparency.
*/
bool GetTransparent() const;
enum Flags {
// Special handling for system graphic.
Flag_System = 1 << 1,
// Special handling for chipset graphic.
// Generates a tile opacity list.
Flag_Chipset = 1 << 2,
// Bitmap will not be written to. This allows blit optimisations because the
// opacity information will not change.
Flag_ReadOnly = 1 << 16
};
enum class BlendMode {
Default, // SRC or OVER depending on the image
Normal, // OP_OVER
NormalWithoutAlpha, // OP_SRC
XOR,
Additive,
Multiply,
Overlay,
Saturate,
Darken,
Lighten,
ColorDodge,
ColorBurn,
Difference,
Exclusion,
SoftLight,
HardLight
};
/**
* Provides opacity information about the image.
* This influences the selected operator when blitting.
*
* @return opacity information
*/
ImageOpacity GetImageOpacity() const;
/**
* Provides opacity information about a tile on a tilemap.
* This influences the selected operator when blitting a tile.
*
* @param x tile x coordinate
* @param y tile y coordinate
*
* @return opacity information
*/
ImageOpacity GetTileOpacity(int x, int y) const;
/**
* Writes PNG converted bitmap to output stream.
*
* @param os output stream that PNG will be output.
* @return true if success, otherwise false.
*/
bool WritePNG(std::ostream& os) const;
/**
* Gets the background color
* Bitmap must have been loaded with the Bitmap::System flag
*
* @return background color.
*/
Color GetBackgroundColor() const;
/**
* Gets the shadow color
* Bitmap must have been loaded with the Bitmap::System flag
*
* @return shadow color.
*/
Color GetShadowColor() const;
/**
* Gets the filename this bitmap was loaded from.
* This will be empty when the origin was not a file.
*
* @return filename
*/
StringView GetFilename() const;
/**
* Gets bpp of the source image.
*
* @return Bpp
*/
int GetOriginalBpp() const;
void CheckPixels(uint32_t flags);
/**
* @param x x-coordinate
* @param y y-coordinate
* @return color at the pixel location
*/
Color GetColorAt(int x, int y) const;
/**
* Draws text to bitmap using the Font::Default() font.
*
* @param x x coordinate where text rendering starts.
* @param y y coordinate where text rendering starts.
* @param color system color index.
* @param text text to draw.
* @param align text alignment.
* @return Where to draw the next glyph
*/
Point TextDraw(int x, int y, int color, StringView text, Text::Alignment align = Text::AlignLeft);
/**
* Draws text to bitmap using the Font::Default() font.
*
* @param rect bounding rectangle.
* @param color system color index.
* @param text text to draw.
* @param align text alignment inside bounding rectangle.
* @return Where to draw the next glyph
*/
Point TextDraw(Rect const& rect, int color, StringView text, Text::Alignment align = Text::AlignLeft);
/**
* Draws text to bitmap using the Font::Default() font.
*
* @param x x coordinate where text rendering starts.
* @param y y coordinate where text rendering starts.
* @param color text color.
* @param text text to draw.
* @return Where to draw the next glyph
*/
Point TextDraw(int x, int y, Color color, StringView text);
/**
* Draws text to bitmap using the Font::Default() font.
*
* @param rect bounding rectangle.
* @param color text color.
* @param text text to draw.
* @param align text alignment inside bounding rectangle.
*/
Point TextDraw(Rect const& rect, Color color, StringView, Text::Alignment align = Text::AlignLeft);
/**
* Blits source bitmap to this one.
*
* @param x x position.
* @param y y position.
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param opacity opacity for blending with bitmap.
* @param blend_mode Blend mode to use.
*/
void Blit(int x, int y, Bitmap const& src, Rect const& src_rect,
Opacity const& opacity, BlendMode blend_mode = BlendMode::Default);
/**
* Blits source bitmap to this one ignoring alpha (faster)
*
* @param x x position.
* @param y y position.
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param opacity opacity for blending with bitmap.
*/
void BlitFast(int x, int y, Bitmap const& src, Rect const& src_rect,
Opacity const& opacity);
/**
* Blits source bitmap in tiles to this one.
*
* @param src_rect source bitmap rect.
* @param src source bitmap.
* @param dst_rect destination rect.
* @param opacity opacity for blending with bitmap.
* @param blend_mode Blend mode to use.
*/
void TiledBlit(Rect const& src_rect, Bitmap const& src, Rect const& dst_rect,
Opacity const& opacity, BlendMode blend_mode = BlendMode::Default);
/**
* Blits source bitmap in tiles to this one.
*
* @param ox tile start x offset.
* @param oy tile start y offset.
* @param src_rect source bitmap rect.
* @param src source bitmap.
* @param dst_rect destination rect.
* @param opacity opacity for blending with bitmap.
* @param blend_mode Blend mode to use.
*/
void TiledBlit(int ox, int oy, Rect const& src_rect, Bitmap const& src, Rect const& dst_rect,
Opacity const& opacity, BlendMode blend_mode = BlendMode::Default);
/**
* Blits source bitmap to this one, making clones across the edges if src crossed a boundary of this.
*
* @param x x position.
* @param y y position.
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param mirror_x Blit a clone in x direction
* @param mirror_Y BLit a clone in y direction
* @param opacity opacity for blending with bitmap.
*/
void EdgeMirrorBlit(int x, int y, Bitmap const& src, Rect const& src_rect, bool mirror_x, bool mirror_y, Opacity const& opacity);
/**
* Blits source bitmap stretched to this one.
*
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param opacity opacity for blending with bitmap.
* @param blend_mode Blend mode to use.
*/
void StretchBlit(Bitmap const& src, Rect const& src_rect,
Opacity const& opacity, BlendMode blend_mode = BlendMode::Default);
/**
* Blits source bitmap stretched to this one.
*
* @param dst_rect destination rect.
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param opacity opacity for blending with bitmap.
* @param blend_mode Blend mode to use.
*/
void StretchBlit(Rect const& dst_rect, Bitmap const& src, Rect const& src_rect,
Opacity const& opacity, BlendMode blend_mode = BlendMode::Default);
/**
* Blit source bitmap flipped.
*
* @param x x position.
* @param y y position.
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param horizontal flip horizontally.
* @param vertical flip vertically.
* @param opacity opacity to apply.
* @param blend_mode Blend mode to use.
*/
void FlipBlit(int x, int y, Bitmap const& src, Rect const& src_rect, bool horizontal, bool vertical,
Opacity const& opacity, BlendMode blend_mode = BlendMode::Default);
/**
* Blits source bitmap with waver, zoom, and opacity effects.
*
* @param x x position.
* @param y y position.
* @param zoom_x x scale factor.
* @param zoom_y y scale factor.
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param depth wave magnitude.
* @param phase wave phase.
* @param opacity opacity.
* @param blend_mode Blend mode to use.
*/
void WaverBlit(int x, int y, double zoom_x, double zoom_y, Bitmap const& src, Rect const& src_rect, int depth, double phase,
Opacity const& opacity, BlendMode blend_mode = BlendMode::Default);
/**
* Blits source bitmap with rotation, zoom, and opacity effects.
*
* @param x x position.
* @param y y position.
* @param ox source origin x.
* @param oy source origin y.
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param angle rotation angle in radians.
* @param zoom_x x scale factor.
* @param zoom_y y scale factor.
* @param opacity opacity.
* @param blend_mode Blend mode to use.
*/
void RotateZoomOpacityBlit(int x, int y, int ox, int oy,
Bitmap const& src, Rect const& src_rect,
double angle, double zoom_x, double zoom_y,
Opacity const& opacity, BlendMode blend_mode = BlendMode::Normal);
/**
* Blits source bitmap with zoom and opacity scaling.
*
* @param x x position.
* @param y y position.
* @param ox source origin x.
* @param oy source origin y.
* @param src source bitmap.
* @param src_rect source bitmap rectangle.
* @param zoom_x x scale factor.
* @param zoom_y y scale factor.
* @param opacity opacity.
* @param blend_mode Blend mode to use.
*/
void ZoomOpacityBlit(int x, int y, int ox, int oy,
Bitmap const& src, Rect const& src_rect,
double zoom_x, double zoom_y,
Opacity const& opacity, BlendMode blend_mode = BlendMode::Default);
/**
* Fills entire bitmap with color.
*
* @param color color for filling.
*/
void Fill(const Color &color);
/**
* Fills bitmap rect with color.
*
* @param dst_rect destination rect.
* @param color color for filling.
*/
void FillRect(Rect const& dst_rect, const Color &color);
/**
* Clears the bitmap with transparent pixels.
*/
void Clear();
/**
* Clears the bitmap rect with transparent pixels.
*
* @param dst_rect destination rect.
*/
void ClearRect(Rect const& dst_rect);
/**
* Rotates bitmap hue.
*
* @param x x position.
* @param y y position.
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param hue hue change, degrees.
*/
void HueChangeBlit(int x, int y, Bitmap const& src, Rect const& src_rect, double hue);
/**
* Adjusts bitmap tone.
*
* @param x x position.
* @param y y position.
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param tone tone to apply.
* @param opacity opacity to apply.
*/
void ToneBlit(int x, int y, Bitmap const& src, Rect const& src_rect, const Tone &tone, Opacity const& opacity);
/**
* Blends bitmap with color.
*
* @param x x position.
* @param y y position.
* @param src source bitmap.
* @param src_rect source bitmap rect.
* @param color color to apply.
* @param opacity opacity to apply.
*/
void BlendBlit(int x, int y, Bitmap const& src, Rect const& src_rect, const Color &color, Opacity const& opacity);
/**
* Flips the bitmap pixels.
*
* @param horizontal flip horizontally (mirror).
* @param vertical flip vertically.
*/
void Flip(bool horizontal, bool vertical);
/**
* Blits source bitmap to this one through a mask bitmap.
*
* @param dst_rect destination rectangle.
* @param mask mask bitmap
* @param mx mask x position
* @param my mask y position
* @param src source bitmap.
* @param sx source x position
* @param sy source y position
*/
void MaskedBlit(Rect const& dst_rect, Bitmap const& mask, int mx, int my, Bitmap const& src, int sx, int sy);
/**
* Blits constant color to this one through a mask bitmap.
*
* @param dst_rect destination rectangle.
* @param mask mask bitmap
* @param mx mask x position
* @param my mask y position
* @param color source color.
*/
void MaskedBlit(Rect const& dst_rect, Bitmap const& mask, int mx, int my, Color const& color);
/**
* Blits source bitmap scaled 2:1, with no transparency.
*
* @param dst_rect destination rectangle.
* @param src source bitmap.
* @param src_rect source bitmap rectangle.
*/
void Blit2x(Rect const& dst_rect, Bitmap const& src, Rect const& src_rect);
/**
* Calculates the bounding rectangle of a transformed rectangle.
*
* @param m transformation matrix.
* @param rect source rectangle.
* @return the bounding rectangle.
*/
static Rect TransformRectangle(const Transform& m, const Rect& rect);
/**
* Blits source bitmap with effects.
* Note: rotation and waver are mutually exclusive.
*
* @param x destination x position.
* @param y destination y position.
* @param ox source origin x.
* @param oy source origin y.
* @param src source bitmap.
* @param src_rect source bitmap rectangle.
* @param opacity opacity to apply.
* @param zoom_x x scale factor.
* @param zoom_y y scale factor.
* @param angle rotation angle.
* @param waver_depth wave magnitude.
* @param waver_phase wave phase.
* @param blend_mode Blend mode to use.
*/
void EffectsBlit(int x, int y, int ox, int oy,
Bitmap const& src, Rect const& src_rect,
Opacity const& opacity,
double zoom_x, double zoom_y, double angle,
int waver_depth, double waver_phase,
BlendMode blend_mode = BlendMode::Default);
static DynamicFormat ChooseFormat(const DynamicFormat& format);
static void SetFormat(const DynamicFormat& format);
static DynamicFormat pixel_format;
static DynamicFormat opaque_pixel_format;
static DynamicFormat image_format;
static DynamicFormat opaque_image_format;
void* pixels();
void const* pixels() const;
int width() const;
int height() const;
int bpp() const;
int pitch() const;
ImageOpacity ComputeImageOpacity() const;
ImageOpacity ComputeImageOpacity(Rect rect) const;
protected:
DynamicFormat format;
ImageOpacity image_opacity = ImageOpacity::Alpha_8Bit;
TileOpacity tile_opacity;
Color bg_color, sh_color;
std::string filename;
/** Bpp of the source image */
int original_bpp;
/** Bitmap data. */
PixmanImagePtr bitmap;
pixman_format_code_t pixman_format;
void Init(int width, int height, void* data, int pitch = 0, bool destroy = true);
void ConvertImage(int& width, int& height, void*& pixels, bool transparent);
static PixmanImagePtr GetSubimage(Bitmap const& src, const Rect& src_rect);
static inline void MultiplyAlpha(uint8_t &r, uint8_t &g, uint8_t &b, const uint8_t &a) {
r = (uint8_t)((int)r * a / 0xFF);
g = (uint8_t)((int)g * a / 0xFF);
b = (uint8_t)((int)b * a / 0xFF);
}
static inline void DivideAlpha(uint8_t &r, uint8_t &g, uint8_t &b, const uint8_t &a) {
if (a == 0)
r = g = b = 0;
else {
r = (uint8_t)((int)r * 0xFF / a);
g = (uint8_t)((int)g * 0xFF / a);
b = (uint8_t)((int)b * 0xFF / a);
}
}
static pixman_format_code_t find_format(const DynamicFormat& format);
/*
* Determines the fastest operator for the operation.
* When a blend_mode is specified the blend mode is used.
*
* @param mask Image mask
* @param blend_mode When >= 0: Force this blend mode as operator
* @return blend mode
*/
pixman_op_t GetOperator(pixman_image_t* mask = nullptr, BlendMode blend_mode = BlendMode::Default) const;
bool read_only = false;
};
struct ImageOut {
int width = 0;
int height = 0;
void* pixels = nullptr;
int bpp = 0;
};
inline ImageOpacity Bitmap::GetImageOpacity() const {
return image_opacity;
}
inline ImageOpacity Bitmap::GetTileOpacity(int x, int y) const {
return tile_opacity.Get(x, y);
}
inline Color Bitmap::GetBackgroundColor() const {
return bg_color;
}
inline Color Bitmap::GetShadowColor() const {
return sh_color;
}
inline int Bitmap::GetWidth() const {
return width();
}
inline int Bitmap::GetHeight() const {
return height();
}
inline Rect Bitmap::GetRect() const {
return Rect(0, 0, width(), height());
}
inline bool Bitmap::GetTransparent() const {
return format.alpha_type != PF::NoAlpha;
}
inline StringView Bitmap::GetFilename() const {
return filename;
}
inline int Bitmap::GetOriginalBpp() const {
return original_bpp;
}
#endif