1 /*
2 * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9 #include "Outline.h"
10
11 #include "Log.h"
12 #include "PixelTool.h"
13 #include "SurfaceTool.h"
14 #include "SurfaceLock.h"
15
16 //-----------------------------------------------------------------
Outline(const SDL_Color & color,int width)17 Outline::Outline(const SDL_Color &color, int width)
18 : m_color(color)
19 {
20 m_width = width;
21 m_pixel = 0;
22 }
23 //-----------------------------------------------------------------
24 /**
25 * Draw outline, use surface colorkey as bg color.
26 */
27 void
drawOnColorKey(SDL_Surface * surface)28 Outline::drawOnColorKey(SDL_Surface *surface)
29 {
30 Uint32 bgKey = surface->format->colorkey;
31 drawOn(surface, bgKey);
32 }
33 //-----------------------------------------------------------------
34 /**
35 * Draw outline on bg color.
36 * @param surface picture with shape to outline
37 * @param bgKey color used for background
38 */
39 void
drawOn(SDL_Surface * surface,Uint32 bgKey)40 Outline::drawOn(SDL_Surface *surface, Uint32 bgKey)
41 {
42 SurfaceLock lock1(surface);
43
44 precomputePixel(surface->format);
45 for (int i = 0; i < m_width; ++i) {
46 drawOneLayer(surface, bgKey);
47 }
48 }
49 //-----------------------------------------------------------------
50 void
precomputePixel(SDL_PixelFormat * format)51 Outline::precomputePixel(SDL_PixelFormat *format)
52 {
53 m_pixel = SDL_MapRGB(format, m_color.r, m_color.g, m_color.b);
54 }
55 //-----------------------------------------------------------------
56 /**
57 * Draw outline with width=1.
58 */
59 void
drawOneLayer(SDL_Surface * surface,Uint32 bgKey)60 Outline::drawOneLayer(SDL_Surface *surface, Uint32 bgKey)
61 {
62 SDL_Surface *copy = SurfaceTool::createClone(surface);
63 drawAlongCopy(surface, bgKey, copy);
64 SDL_FreeSurface(copy);
65 }
66 //-----------------------------------------------------------------
67 /**
68 * Draw outline with width=1.
69 * Cloned surface will be used as a model. It will not be modified.
70 * Destination surface must be locked.
71 */
72 void
drawAlongCopy(SDL_Surface * surface,Uint32 bgKey,SDL_Surface * copy)73 Outline::drawAlongCopy(SDL_Surface *surface, Uint32 bgKey, SDL_Surface *copy)
74 {
75 SurfaceLock lock1(copy);
76
77 for (int py = 0; py < surface->h; ++py) {
78 for (int px = 0; px < surface->w; ++px) {
79 if (PixelTool::getPixel(copy, px, py) != bgKey) {
80 fillNeighbourhood(surface, bgKey, px, py);
81 }
82 }
83 }
84 }
85 //-----------------------------------------------------------------
86 /**
87 * Fill neighboors around this point.
88 * Neighbours with bgKey will be filled.
89 * Surface must be locked.
90 * m_pixel must be precomputed.
91 */
92 void
fillNeighbourhood(SDL_Surface * surface,Uint32 bgKey,int x,int y)93 Outline::fillNeighbourhood(SDL_Surface *surface, Uint32 bgKey, int x, int y)
94 {
95 //TODO: optimize for speed
96 if (x > 0 && PixelTool::getPixel(surface, x - 1, y) == bgKey) {
97 PixelTool::putPixel(surface, x - 1, y, m_pixel);
98 }
99 if (y > 0 && PixelTool::getPixel(surface, x, y - 1) == bgKey) {
100 PixelTool::putPixel(surface, x, y - 1, m_pixel);
101 }
102
103 if (x + 1 < surface->w &&
104 PixelTool::getPixel(surface, x + 1, y) == bgKey)
105 {
106 PixelTool::putPixel(surface, x + 1, y, m_pixel);
107 }
108 if (y + 1 < surface->h &&
109 PixelTool::getPixel(surface, x, y + 1) == bgKey)
110 {
111 PixelTool::putPixel(surface, x, y + 1, m_pixel);
112 }
113 }
114
115
116