/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "common/textconsole.h" #include "common/util.h" #include "graphics/VectorRenderer.h" #define VECTOR_RENDERER_FAST_TRIANGLES namespace Graphics { /******************************************************************** * DRAWSTEP handling functions ********************************************************************/ void VectorRenderer::drawStep(const Common::Rect &area, const Common::Rect &clip, const DrawStep &step, uint32 extra) { if (step.bgColor.set) setBgColor(step.bgColor.r, step.bgColor.g, step.bgColor.b); if (step.fgColor.set) setFgColor(step.fgColor.r, step.fgColor.g, step.fgColor.b); if (step.bevelColor.set) setBevelColor(step.bevelColor.r, step.bevelColor.g, step.bevelColor.b); if (step.gradColor1.set && step.gradColor2.set) setGradientColors(step.gradColor1.r, step.gradColor1.g, step.gradColor1.b, step.gradColor2.r, step.gradColor2.g, step.gradColor2.b); setShadowOffset(_disableShadows ? 0 : step.shadow); setBevel(step.bevel); setGradientFactor(step.factor); setStrokeWidth(step.stroke); setFillMode((FillMode)step.fillMode); setClippingRect(applyStepClippingRect(area, clip, step)); _dynamicData = extra; (this->*(step.drawingCall))(area, step); } Common::Rect VectorRenderer::applyStepClippingRect(const Common::Rect &area, const Common::Rect &clip, const DrawStep &step) { if (step.clip == Common::Rect()) { return clip; } Common::Rect finalClip = clip; if (step.clip.left > 0) { finalClip.left = area.left + step.clip.left; } else if (step.clip.left < 0) { finalClip.left = area.right + step.clip.left; } if (step.clip.top > 0) { finalClip.top = area.top + step.clip.top; } else if (step.clip.top < 0) { finalClip.top = area.bottom + step.clip.top; } if (step.clip.right > 0) { finalClip.right = area.left + step.clip.right; } else if (step.clip.right < 0) { finalClip.right = area.right + step.clip.right; } if (step.clip.bottom > 0) { finalClip.bottom = area.top + step.clip.bottom; } else if (step.clip.bottom < 0) { finalClip.bottom = area.bottom + step.clip.bottom; } finalClip.clip(clip); return finalClip; } int VectorRenderer::stepGetRadius(const DrawStep &step, const Common::Rect &area) { int radius = 0; if (step.radius == 0xFF) radius = MIN(area.width(), area.height()) / 2; else radius = step.radius; if (step.scale != (1 << 16) && step.scale != 0) radius = (radius * step.scale) >> 16; return radius; } void VectorRenderer::stepGetPositions(const DrawStep &step, const Common::Rect &area, uint16 &in_x, uint16 &in_y, uint16 &in_w, uint16 &in_h) { if (!step.autoWidth) { in_w = step.w == -1 ? area.height() : step.w; switch (step.xAlign) { case Graphics::DrawStep::kVectorAlignManual: if (step.x >= 0) in_x = area.left + step.x + step.padding.left; else in_x = area.left + area.width() + step.x + step.padding.left; // value relative to the opposite corner. break; case Graphics::DrawStep::kVectorAlignCenter: in_x = area.left + (area.width() / 2) - (in_w / 2) + ((step.padding.left + step.padding.right ) / 2); break; case Graphics::DrawStep::kVectorAlignLeft: in_x = area.left + step.padding.left; break; case Graphics::DrawStep::kVectorAlignRight: in_x = area.left + area.width() - in_w - step.padding.right; break; default: error("Vertical alignment in horizontal data"); } } else { in_x = area.left + step.padding.left; in_w = area.width() - step.padding.left - step.padding.right; } if (!step.autoHeight) { in_h = step.h == -1 ? area.width() : step.h; switch (step.yAlign) { case Graphics::DrawStep::kVectorAlignManual: if (step.y >= 0) in_y = area.top + step.y + step.padding.top; else in_y = area.top + area.height() + step.y + step.padding.top; // relative break; case Graphics::DrawStep::kVectorAlignCenter: in_y = area.top + (area.height() / 2) - (in_h / 2) + ((step.padding.top + step.padding.bottom ) / 2); break; case Graphics::DrawStep::kVectorAlignTop: in_y = area.top + step.padding.top; break; case Graphics::DrawStep::kVectorAlignBottom: in_y = area.top + area.height() - in_h - step.padding.bottom; break; default: error("Horizontal alignment in vertical data"); } } else { in_y = area.top + step.padding.top; in_h = area.height() - step.padding.top - step.padding.bottom; } if (step.scale != (1 << 16) && step.scale != 0) { in_x = (in_x * step.scale) >> 16; in_y = (in_y * step.scale) >> 16; in_w = (in_w * step.scale) >> 16; in_h = (in_h * step.scale) >> 16; } } } // End of namespace Graphics