]> git.localhorst.tv Git - l2e.git/blob - src/graphics/Frame.cpp
handle line breaks in Font::DrawString
[l2e.git] / src / graphics / Frame.cpp
1 /*
2  * Frame.cpp
3  *
4  *  Created on: Aug 7, 2012
5  *      Author: holy
6  */
7
8 #include "Frame.h"
9
10 #include "Texture.h"
11 #include "../loader/Interpreter.h"
12 #include "../loader/TypeDescription.h"
13
14 using geometry::Vector;
15 using loader::FieldDescription;
16 using loader::Interpreter;
17 using loader::TypeDescription;
18
19 namespace graphics {
20
21 // TODO: maybe create a cache for frames?
22 void Frame::Draw(SDL_Surface *dest, const Vector<int> &position, int width, int height) const {
23         if (!surface) {
24                 SDL_Rect rect;
25                 rect.x = position.X();
26                 rect.y = position.Y();
27                 rect.w = width;
28                 rect.h = height;
29                 SDL_FillRect(dest, &rect, SDL_MapRGB(dest->format, 0xFF, 0x00, 0x00));
30                 return;
31         }
32         // top-left corner
33         SDL_Rect srcRect;
34         srcRect.x = offset.X();
35         srcRect.y = offset.Y();
36         srcRect.w = BorderWidth();
37         srcRect.h = BorderHeight();
38         SDL_Rect destRect;
39         destRect.x = position.X();
40         destRect.y = position.Y();
41         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
42
43         // top border
44         Texture(surface, Vector<int>(RepeatWidth(), BorderHeight()), Vector<int>(offset.X() + BorderWidth(), offset.Y()))
45         .Render(dest, Vector<int>(position.X() + BorderWidth(), position.Y()), Vector<int>(position.X() + width - BorderWidth(), position.Y() + BorderHeight()));
46
47         // top-right corner
48         srcRect.x = offset.X() + RepeatWidth() + BorderWidth();
49         srcRect.w = BorderWidth();
50         destRect.x = position.X() + width - BorderWidth();
51         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
52
53         // left border
54         Texture(surface, Vector<int>(BorderWidth(), RepeatHeight()), Vector<int>(offset.X(), offset.Y() + BorderHeight()))
55         .Render(dest, Vector<int>(position.X(), position.Y() + BorderHeight()), Vector<int>(position.X() + BorderWidth(), position.Y() + height - BorderHeight()));
56
57         // center fill
58         Texture(surface, RepeatSize(), Vector<int>(offset.X() + BorderWidth(), offset.Y() + BorderHeight()))
59         .Render(dest, position + BorderSize(), position + Vector<int>(width, height) - BorderSize());
60
61         // right border
62         Texture(surface, Vector<int>(BorderWidth(), RepeatHeight()), Vector<int>(offset.X() + BorderWidth() + RepeatWidth(), offset.Y() + BorderHeight()))
63         .Render(dest, Vector<int>(position.X() + width - BorderWidth(), position.Y() + BorderHeight()), Vector<int>(position.X() + width, position.Y() + height - BorderHeight()));
64
65         // bottom-left corner
66         srcRect.x = offset.X();
67         srcRect.y = offset.Y() + BorderHeight() + RepeatHeight();
68         srcRect.w = BorderWidth();
69         srcRect.h = BorderHeight();
70         destRect.x = position.X();
71         destRect.y = position.Y() + height - BorderHeight();
72         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
73
74         // bottom border
75         Texture(surface, Vector<int>(RepeatWidth(), BorderHeight()), Vector<int>(offset.X() + BorderWidth(), offset.Y() + BorderHeight() + RepeatHeight()))
76         .Render(dest, Vector<int>(position.X() + BorderWidth(), position.Y() + height - BorderHeight()), Vector<int>(position.X() + width - BorderWidth(), position.Y() + height));
77
78         // bottom-right corner
79         srcRect.x = offset.X() + BorderWidth() + RepeatWidth();
80         srcRect.w = BorderWidth();
81         destRect.x = position.X() + width - BorderWidth();
82         SDL_BlitSurface(surface, &srcRect, dest, &destRect);
83 }
84
85
86 void Frame::CreateTypeDescription() {
87         Frame f;
88
89         TypeDescription &td(TypeDescription::Create(TYPE_ID, "Frame"));
90         td.SetDescription(
91                         "A frame is basically a border + a background texture.\n"
92                         "It splits an image into 3*3 parts where the edges are kept as is and the sides and the middle part are repeated as needed.");
93         td.SetConstructor(&Construct);
94         td.SetSize(sizeof(Frame));
95
96         td.AddField("image", FieldDescription(((char *)&f.surface) - ((char *)&f), Interpreter::IMAGE_ID).SetReferenced().SetDescription("the underlying graphic from which the frame parts are cut"));
97         td.AddField("border", FieldDescription(((char *)&f.borderSize) - ((char *)&f), Interpreter::VECTOR_ID).SetDescription("size of the border part, dimensions of top-left corner"));
98         td.AddField("repeat", FieldDescription(((char *)&f.repeatSize) - ((char *)&f), Interpreter::VECTOR_ID).SetDescription("size of the repeat part, dimensions of a single tile of the background texture"));
99         td.AddField("offset", FieldDescription(((char *)&f.offset) - ((char *)&f), Interpreter::VECTOR_ID).SetDescription("offset into the image where to start cutting, coordinates of the top-left corner on the image"));
100 }
101
102 void Frame::Construct(void *data) {
103         new (data) Frame;
104 }
105
106 }