// // Style.cpp: implementation file for the Style class and Stack class. // // Author: Darren Sessions // // // Description: // // The Stack class defines the User API of the Style Toolkit. The Style // class is used to paint the stacks. // // History // Version 1.1 - 2008 August 1 // - More features added // // Version 1.1 - 2008 July 22 // - Initial public release // // License: // This software is released under the Code Project Open License (CPOL), // which may be found here: http://www.codeproject.com/info/eula.aspx // You are free to use this software in any way you like, except that you // may not sell this source code. // // This software is provided "as is" with no expressed or implied warranty. // I accept no liability for any damage or loss of business that this // software may cause. // /////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Style.h" Style::Style() { // pre allocate some stack space m_Stacks.reserve(5); } Style::~Style() { } //============================================================================= // // AddStack() // // Purpose: Adds a stack to the top of this style // // Parameters: stack - [in] the stack to add // // Returns: None // int Style::AddStack(Stack& stack) { m_Stacks.push_back(stack); return (int)(m_Stacks.size() - 1); } //============================================================================= // // PaintStyle() // // Purpose: Paints all the stacks for this style // // Parameters: pDevC - [in] the device context // rect - [in] the bounding rect for this style // // Returns: None // void Style::PaintStyle(CDC* pDevC, CRect rect) { MemDC pDC(pDevC, rect, TRUE); Graphics gdi(pDC->m_hDC); // default smoothing mode gdi.SetSmoothingMode(SmoothingModeAntiAlias); gdi.SetTextRenderingHint(TextRenderingHintClearTypeGridFit); // paint all stacks for(stack = m_Stacks.begin(); stack != m_Stacks.end(); ++stack) { if((*stack).Frame.bUseBitmap) { // copy the bitmap to the DC pDC->BitBlt((*stack).Frame.frect.X, (*stack).Frame.frect.Y, (*stack).Frame.frect.Width, (*stack).Frame.frect.Height, (*stack).GetDC(), 0, 0, SRCCOPY ); } else { // the first call to PaintStyle will create all the bitmaps here (*stack).PaintStack(pDC, &gdi); } } } //============================================================================= // // SetPosition() // // Purpose: Sets the origin of all the stacks and layers // // Parameters: x - [in] the x offset // y - [in] the y offset // // Returns: None // void Style::SetPosition(int x, int y) { // iterate all stacks for(stack = m_Stacks.begin(); stack != m_Stacks.end(); ++stack) { ASSERT(!((*stack).Frame.frect.Width == 0 && (*stack).Frame.frect.Height == 0)); (*stack).SetPosition(x, y); } } //============================================================================= // // Regenerate() // // Purpose: Marks all the stacks in the style for regeneration // // Parameters: None // // Returns: None // void Style::Regenerate() { // iterate all stacks for(stack = m_Stacks.begin(); stack != m_Stacks.end(); ++stack) { (*stack).Regenerate(); } } //============================================================================= int Style::GetTopIndex() //============================================================================= { return (int)(m_Stacks.size() - 1); } //============================================================================= // operator = Stack& Stack::operator=(const Stack& other) //============================================================================= { Layers::m_Layers.clear(); Layers::Copy(other); return *this; } //============================================================================= // operator += Stack& Stack::operator+=(const Stack& other) //============================================================================= { // the region indexes need to be adjusted to add // the layers beneath it int cnt =(int)m_Layers.size(); Layers::CopyLayers(other); for(layer = m_Layers.begin() + cnt; layer != m_Layers.end(); ++layer) { // just adjust all of them even if they don't apply (*layer).rgnIndex[0] += cnt; (*layer).rgnIndex[1] += cnt; } return *this; } //============================================================================= // operator + Stack operator+(const Stack& lhs, const Stack& rhs) //============================================================================= { return Stack(lhs)+=rhs; } //============================================================================= // GDI constructor with boundaries Stack::Stack(SRect sr) //============================================================================= { Init(); MakeFrame(sr.rect); } //============================================================================= // GDI constructor with Initial layer Stack::Stack(SRect sr, Clr clr) //============================================================================= { Init(); MakeFrame(sr.rect); AddLayer(sr.rect, clr); } //============================================================================= // // AddLayer() // // Purpose: Adds a layer to the stack. A transparent layer will be created // and set to the Frames rect just prior to painting // // Parameters: None // // Returns: None // int Stack::AddLayer() { OPERATION Layer; ::ZeroMemory(&Layer, sizeof(OPERATION)); m_Layers.push_back(Layer); return (int)(m_Layers.size() - 1); } //============================================================================= // // AddLayer() // // Purpose: Adds a layer to the stack. If only the rect is passed // a transparent layer will be created // // Parameters: sr - [in] Rect boundary of this layer // clr - [in] optional - color of this layer // // Returns: None // int Stack::AddLayer(SRect sr, Clr clr) { OPERATION Layer; ::ZeroMemory(&Layer, sizeof(OPERATION)); Layer.lrect = sr.rect; Layer.clr1 = clr.value; m_Layers.push_back(Layer); return (int)(m_Layers.size() - 1); } //============================================================================= // // SetRect() // // Purpose: Sets the size and position of the stack relative to the // parent's origin (the parent is the Style that will paint // this object) // // Parameters: rect - [in] CRect object // // Returns: None // void Stack::SetRect(SRect rect) { MakeFrame(rect); } //============================================================================= // // SetShape() // // Purpose: Sets the shape of the stacks borders to the passed argurmen // // Parameters: shape - [in] one of LayerShapes // radius - [in] radius of corner for ROUNDRECT type shape // // Returns: None // void Stack::SetShape(int shape, int radius) { Layers::SetShape(shape, radius); } //============================================================================= // // Regenerate() // // Purpose: Marks the stack to be regenerated on the next paint operation. // If a layer index is passed, it will reset all of the layer rects // above and including the index to zero, causing them to be // recalcculated from the frame rect // // Parameters: x - [in] the x offset // y - [in] the y offset // // Returns: None // void Stack::Regenerate(int layerIdx) { Layers::Regenerate(layerIdx); } //============================================================================= // // SetPosition() // // Purpose: Moves the frame and all the layers in the stack to the x y position // // Parameters: x, y - [in] the new position // // Returns: None // void Stack::SetPosition(int x, int y) { int xoff = x - Frame.frect.X; int yoff = y - Frame.frect.Y; // set the frame origin Frame.frect.X = x; Frame.frect.Y = y; // iterate all the layers for(layer = m_Layers.begin(); layer != m_Layers.end(); ++layer) { (*layer).lrect.X += xoff; (*layer).lrect.Y += yoff; } } //============================================================================= // // FillSolid() // // Purpose: Defines the layer as a solid fill // // Parameters: cr - [in] the rect for this layer // clr1 - [in] color for this layer // // Returns: index to layer added // int Stack::FillSolid(SRect cr, Clr color) { int layer = AddLayer(); m_Layers[layer].lrect = cr.rect; m_Layers[layer].clr1 = color.value; m_Layers[layer].LayerType = SOLID; return layer; } //============================================================================= // // FillSolid() // // Purpose: Defines the layer as a solid fill // // Parameters: clr1 - [in] color for this layer // // Returns: index to layer added // int Stack::FillSolid(Clr color) { int layer = AddLayer(); m_Layers[layer].clr1 = color.value; m_Layers[layer].LayerType = SOLID; return layer; } //============================================================================= // // FillGrad2() // // Purpose: Defines the layer as a 2 color gradient // // Parameters: rect - [in] Rectangle for this layer // style - [in] Gradient style - HORIZ, VERT, DIAGF, DIAGR // clr1 - [in] Begin color for gradient // clr2 - [in] End color for gradient // diffpt - [in] Diffusion point (-1.0, 1.0) // negative values mean diffuse relative to clr2 position // // Returns: index to layer added // int Stack::FillGrad2(SRect sr, int style, Clr clr1, Clr clr2, float diffpt) { int layer = AddLayer(); m_Layers[layer].lrect = sr.rect; m_Layers[layer].gradMode = style; m_Layers[layer].clr1 = clr1.value; m_Layers[layer].clr2 = clr2.value; m_Layers[layer].rParams[0] = diffpt; m_Layers[layer].LayerType = BIGRAD; return layer; } //============================================================================= // // FillGrad2() // // Purpose: Defines the layer as a 2 color gradient // // Parameters: style - [in] Gradient style - HORIZ, VERT, DIAGF, DIAGR // clr1 - [in] Begin color for gradient // clr2 - [in] End color for gradient // diffpt - [in] Diffusion point (-1.0, 1.0) // negative values mean diffuse relative to clr2 position // // Returns: index to layer added // int Stack::FillGrad2(int style, Clr clr1, Clr clr2, float diffpt) { int layer = AddLayer(); m_Layers[layer].gradMode = style; m_Layers[layer].rParams[0] = diffpt; m_Layers[layer].clr1 = clr1.value; m_Layers[layer].clr2 = clr2.value; m_Layers[layer].LayerType = BIGRAD; return layer; } //============================================================================= // // FillRadial() // // Purpose: Defines the layer as a 2 radial gradient // // Parameters: rect - [in] Rectangle for this layer // clr1 - [in] Begin color for gradient // clr2 - [in] End color for gradient // // Returns: index to layer added // int Stack::FillRadial(SRect sr, Clr clr1, Clr clr2) { int layer = AddLayer(); m_Layers[layer].lrect = sr.rect; m_Layers[layer].clr1 = clr1.value; m_Layers[layer].clr2 = clr2.value; m_Layers[layer].LayerType = RADIAL; return layer; } //============================================================================= // // FillRadial() // // Purpose: Defines the layer as a 2 radial gradient // // Parameters: clr1 - [in] Begin color for gradient // clr2 - [in] End color for gradient // // Returns: index to layer added // int Stack::FillRadial(Clr clr1, Clr clr2) { int layer = AddLayer(); m_Layers[layer].clr1 = clr1.value; m_Layers[layer].clr2 = clr2.value; m_Layers[layer].LayerType = RADIAL; return layer; } //============================================================================= // // FillGrad3() // // Purpose: Defines the layer as a 3 color gradient // // Parameters: cr - [in] rect for this layer // style - [in] Gradient style - HORIZ, VERT, DIAGF, DIAGR // clr1 - [in] Begin color for gradient // clr2 - [in] Middle color for gradient // clr3 - [in] End color for gradient // diffpt - [in] Diffusion point (-1.0, 1.0) (future) // // Returns: index to layer added //=============================================================================/// int Stack::FillGrad3(SRect sr, int style, Clr clr1, Clr clr2, Clr clr3, float diffpt) { int layer = AddLayer(); m_Layers[layer].lrect = sr.rect; m_Layers[layer].gradMode = style; m_Layers[layer].rParams[0] = diffpt; m_Layers[layer].clr1 = clr1.value; m_Layers[layer].clr2 = clr2.value; m_Layers[layer].clr3 = clr3.value; m_Layers[layer].LayerType = TRIGRAD; return layer; } //============================================================================= // // FillGrad3() // // Purpose: Defines the layer as a 3 color gradient // // Parameters: style - [in] Gradient style - HORIZ, VERT, DIAGF, DIAGR // clr1 - [in] Begin color for gradient // clr2 - [in] Middle color for gradient // clr3 - [in] End color for gradient // diffpt - [in] Diffusion point (0.0, 1.0) // // Returns: index to layer added //=============================================================================/// int Stack::FillGrad3(int style, Clr clr1, Clr clr2, Clr clr3, float diffpt) { int layer = AddLayer(); m_Layers[layer].gradMode = style; m_Layers[layer].rParams[0] = diffpt; m_Layers[layer].clr1 = clr1.value; m_Layers[layer].clr2 = clr2.value; m_Layers[layer].clr3 = clr3.value; m_Layers[layer].LayerType = TRIGRAD; return layer; } //============================================================================= // // SetOuterBorder() // // Purpose: Sets the Stacks border parameters // // Parameters: width - [in] the border width // clr - [in] color of border or upper left color if both are defined // brclr - [in] optional - bottom right color // // Returns: None // void Stack::SetOuterBorder(int width, Clr clr, Clr brclr) { Frame.OuterBorder.width = width; Frame.OuterBorder.ulclr = clr.value; Frame.OuterBorder.brclr = brclr.value; } void Stack::SetOuterBorder(int width, Clr clr) { Frame.OuterBorder.width = width; Frame.OuterBorder.ulclr = clr.value; Frame.OuterBorder.brclr = clr.value; } //============================================================================= // // SetMiddleBorder() // // Purpose: Sets the Stacks border parameters // // Parameters: width - [in] the border width // clr - [in] color of border or upper left color if both are defined // brclr - [in] optional - bottom right color // // Returns: None // void Stack::SetMiddleBorder(int width, Clr clr, Clr brclr) { Frame.MiddleBorder.width = width; Frame.MiddleBorder.ulclr = clr.value; Frame.MiddleBorder.brclr = brclr.value; } void Stack::SetMiddleBorder(int width, Clr clr) { Frame.MiddleBorder.width = width; Frame.MiddleBorder.ulclr = clr.value; Frame.MiddleBorder.brclr = clr.value; } //============================================================================= // // SetInnerBorder() // // Purpose: Sets the Stacks border parameters // // Parameters: width - [in] the border width // clr - [in] color of border or upper left color if both are defined // brclr - [in] optional - bottom right color // // Returns: None // void Stack::SetInnerBorder(int width, Clr clr, Clr brclr) { Frame.InnerBorder.width = width; Frame.InnerBorder.ulclr = clr.value; Frame.InnerBorder.brclr = brclr.value; } void Stack::SetInnerBorder(int width, Clr clr) { Frame.InnerBorder.width = width; Frame.InnerBorder.ulclr = clr.value; Frame.InnerBorder.brclr = clr.value; } //============================================================================= // // FillBar() // // Purpose: Adds a gradient bar effect to one of edges // // Parameters: cr - [in] the rectangle containing this edge // type - [in] bar type - TOP_EDGE, LEFT_EDGE, RIGHT_EDGE, BOTTOM_EDGE // width - [in] the bar width // tlclr - [in] top or left color // brclr - [in] bottom or right color // // Returns: index to layer added // int Stack::FillBar(SRect sr, int type, int width, Clr tlclr, Clr brclr) { int layer = AddLayer(); m_Layers[layer].lrect = sr.rect; m_Layers[layer].LayerType = type; m_Layers[layer].width = width; m_Layers[layer].clr1 = tlclr.value; m_Layers[layer].clr2 = brclr.value; m_Layers[layer].clr3 = brclr.value; return layer; } //============================================================================= // // FillBar() // // Purpose: Adds a gradient bar effect to one of edges // // Parameters: type - [in] bar type - TOP_EDGE, LEFT_EDGE, RIGHT_EDGE, BOTTOM_EDGE // width - [in] the bar width // tlclr - [in] top or left color // brclr - [in] bottom or right color // // Returns: index to layer added // int Stack::FillBar(int type, int width, Clr tlclr, Clr brclr) { int layer = AddLayer(); m_Layers[layer].LayerType = type; m_Layers[layer].width = width; m_Layers[layer].clr1 = tlclr.value; m_Layers[layer].clr2 = brclr.value; m_Layers[layer].clr3 = brclr.value; return layer; } //============================================================================= // // FillBar() // // Purpose: Adds a gradient bar effect to one of edges // // Parameters: cr - [in] the rectangle containing this edge // type - [in] bar type - TOP_EDGE, LEFT_EDGE, RIGHT_EDGE, BOTTOM_EDGE // width - [in] the bar width // tlclr - [in] top or left color // mclr - [in] middle color // brclr - [in] bottom or right color // profile - [in] array of 3 floats defining trinagle gradient // // Returns: index to layer added // int Stack::FillBar(SRect sr, int type, int width, Clr tlclr, Clr mclr, Clr brclr, float* profile) { int layer = AddLayer(); m_Layers[layer].lrect = sr.rect; m_Layers[layer].LayerType = type; m_Layers[layer].width = width; m_Layers[layer].clr1 = tlclr.value; m_Layers[layer].clr2 = mclr.value; m_Layers[layer].clr3 = brclr.value; memcpy(m_Layers[layer].rParams, profile, 3*sizeof(float)); return layer; } //============================================================================= // // FillBar() // // Purpose: Adds a gradient bar effect to one of edges // // Parameters: type - [in] bar type - TOP_EDGE, LEFT_EDGE, RIGHT_EDGE, BOTTOM_EDGE // width - [in] the bar width // tlclr - [in] top or left color // mclr - [in] middle color // brclr - [in] bottom or right color // profile - [in] array of 3 floats defining trinagle gradient // // Returns: index to layer added // int Stack::FillBar(int type, int width, Clr tlclr, Clr mclr, Clr brclr, float* profile) { int layer = AddLayer(); m_Layers[layer].LayerType = type; m_Layers[layer].width = width; m_Layers[layer].clr1 = tlclr.value; m_Layers[layer].clr2 = mclr.value; m_Layers[layer].clr3 = brclr.value; memcpy(m_Layers[layer].rParams, profile, 3*sizeof(float)); return layer; } //============================================================================= // // FillWrap() // // Purpose: Adds a gradient of size width to the rect and then tiles // with the tile mode // // Parameters: type - [in] tile type // width - [in] the width of the tiled piece // tlclr - [in] top or left color // mclr - [in] middle color // brclr - [in] bottom or right color // // Returns: index to layer added // int Stack::FillWrap(int type, int width, Clr tlclr, Clr mclr, Clr brclr) { int layer = AddLayer(); m_Layers[layer].LayerType = WRAP; m_Layers[layer].width = width; m_Layers[layer].clr1 = tlclr.value; m_Layers[layer].clr2 = mclr.value; m_Layers[layer].clr3 = brclr.value; return layer; } //============================================================================= // // FillWrap() // // Purpose: Adds a gradient of size width to the rect and then tiles // with the tile mode // // Parameters: type - [in] tile type // width - [in] the width of the tiled piece // tlclr - [in] top or left color // mclr - [in] middle color // brclr - [in] bottom or right color // // Returns: index to layer added // int Stack::FillWrap(SRect sr, int type, int width, Clr tlclr, Clr mclr, Clr brclr) { int layer = AddLayer(); m_Layers[layer].lrect = sr.rect; m_Layers[layer].LayerType = WRAP; m_Layers[layer].width = width; m_Layers[layer].clr1 = tlclr.value; m_Layers[layer].clr2 = mclr.value; m_Layers[layer].clr3 = brclr.value; return layer; } //============================================================================= // // CreateRgn() // // Purpose: Create a region // // Parameters: cr - [in] the rectangle bounding the region // shape - [in] the clipping shape // // Returns: index to layer referencing this clip region // int Stack::CreateRgn(SRect sr, int shape) { int layer = AddLayer(); m_Layers[layer].lrect = sr.rect; m_Layers[layer].LayerType = CREATERGN; m_Layers[layer].LayerShape = shape; return layer; } //============================================================================= // // CombineRgnModify() // // Purpose: Combines two clipping regions using the passed clipping mode // The resultRgn will be modified // // Parameters: resultRgn - [in] this region will contain the combined result // combineRgn - [in] this region will be combined with the resultRgn // mode - [in] the clipping mode // // Returns: index to layer added // int Stack::CombineRgnModify(int resultRgn, int combineRgn, int mode) { int layer = AddLayer(); m_Layers[layer].LayerType = COMBINEMOD; m_Layers[layer].clipMode = mode; m_Layers[layer].rgnIndex[0] = resultRgn; m_Layers[layer].rgnIndex[1] = combineRgn; return layer; } //============================================================================= // // CombineRgnCreate() // // Purpose: Combines two clipping regions using the passed clipping mode // The combined result will be placed in a new region // // Parameters: rgn1 - [in] this region will copied first // rgn2 - [in] this region will be combined with the copy // mode - [in] the clipping mode // // Returns: index to layer added // int Stack::CombineRgnCreate(int rgn1, int rgn2, int mode) { ASSERT(rgn1 != NULL && rgn2 != NULL); int layer = AddLayer(); m_Layers[layer].LayerType = COMBINENEW; m_Layers[layer].clipMode = mode; m_Layers[layer].rgnIndex[0] = rgn1; m_Layers[layer].rgnIndex[1] = rgn2; return layer; } //============================================================================= // // ApplyClipRgn() // // Purpose: Replace the current clipping region // // Parameters: region - [in] the new region // // Returns: index to layer added // int Stack::ApplyClipRgn(int region) { int layer = AddLayer(); m_Layers[layer].LayerType = APPLYCLIP; m_Layers[layer].rgnIndex[0] = region; return layer; } //============================================================================= // // RestoreClipRgn() // // Purpose: Restores the clipping region to the Fram region // // Parameters: None // // Returns: index to layer added // int Stack::RestoreClipRgn() { int layer = AddLayer(); m_Layers[layer].LayerType = RESTORECLIP; return layer; } //============================================================================= // // SetSmoothing() // // Purpose: Set the current smoothing mode // // Parameters: mode - [in] one of SmoothModes // // Returns: index to layer added // int Stack::SetSmoothing(int mode) { int layer = AddLayer(); m_Layers[layer].LayerType = SETSMOOTH; m_Layers[layer].clipMode = mode; return layer; } //============================================================================= // // RestoreSmoothing() // // Purpose: Set the current smoothing mode // // Parameters: mode - [in] one of SmoothModes // // Returns: index to layer added // int Stack::RestoreSmoothing() { int layer = AddLayer(); m_Layers[layer].LayerType = RESTORESMOOTH; return layer; } //============================================================================= // // ApplyBlur() // // Purpose: Applies a blur effect to the current frame // // Parameters: width - [in] the amount of blur // // Returns: index to layer added // int Stack::FillBlur(int region, Clr clr, int width) { int layer = AddLayer(); m_Layers[layer].clr1 = clr.value; m_Layers[layer].LayerType = REGIONBLUR; m_Layers[layer].width = width; m_Layers[layer].rgnIndex[0] = region; return layer; } //============================================================================= // // AddImage() // // Purpose: Adds an image to the stack // // Parameters: pt - [in] offset into the layer rect // id - [in] resource id // type - [in] resource type // clip - [in] TRUE if clipped, else streched // xform - [in] apply image xform - one of ImageXForms // // Returns: index to layer added // int Stack::AddImage(SPoint sp, UINT id, LPCTSTR type, int clip, int xform) { IMAGEINFO ii; ::ZeroMemory(&ii, sizeof(IMAGEINFO)); ii.destpt = sp.point; ii.resID = id; ii.resType = type; ii.xform = xform; ii.clip = clip; Layers::m_Images.push_back(ii); int layer = AddLayer(); m_Layers[layer].LayerType = IMAGE; m_Layers[layer].imgIndex = (int)(m_Images.size() - 1); return layer; } //============================================================================= // // AddImage() // // Purpose: Adds an image to the stack // // Parameters: dest - [in] images destination within the layer rect // src - [in] src rect within the image // id - [in] resource id // type - [in] resource type // clip - [in] TRUE if clipped, else streched // xform - [in] apply image xform - one of ImageXForms // // Returns: index to layer added // int Stack::AddImage(SPoint dest, SPoint src, UINT id, LPCTSTR type, int clip, int xform) { IMAGEINFO ii; ::ZeroMemory(&ii, sizeof(IMAGEINFO)); ii.destpt = dest.point; ii.srcpt = src.point; ii.resID = id; ii.resType = type; ii.xform = xform; ii.clip = clip; m_Images.push_back(ii); int layer = AddLayer(); m_Layers[layer].LayerType = IMAGE; m_Layers[layer].imgIndex = (int)(m_Images.size() - 1); return layer; } //============================================================================= // // AddString() // // Purpose: Adds a string to the stack // // Parameters: str - [in] the CString to add // offset - [in] CPoint offset into the Frame rect // clr - [in] sting color // size - [in] vertical size of the string // style - [in] the font style (one of enum FontStyles) // name - [in] Font Family name string // // Returns: index to layer added // int Stack::AddString(CString str, SPoint offset, Clr clr, int size, int style, WCHAR* name) { TEXTINFO ti; ::ZeroMemory(&ti, sizeof(TEXTINFO)); memcpy(ti.fname, name, 2*wcslen(name)); ti.fsize = size; ti.fstyle = style; ti.foffset.X = (float)offset.point.X; ti.foffset.Y = (float)offset.point.Y; #ifdef _MBCS // convert the CString to wstring size_t cssize = strlen(str) + 1; size_t wcsize = cssize*sizeof(wchar_t); ti.string.reserve(wcsize); wchar_t *pwstr = (wchar_t*)malloc(wcsize); MultiByteToWideChar(CP_ACP, 0, str, (int)cssize, pwstr, (int)wcsize); ti.string = pwstr; m_Strings.push_back(ti); free(pwstr); #else ti.string = str; m_Strings.push_back(ti); #endif int layer = AddLayer(); m_Layers[layer].LayerType = STRING; m_Layers[layer].strIndex = (int)(m_Strings.size() - 1); m_Layers[layer].clr1 = clr.value; return layer; } //============================================================================= // // AddAlignString() // // Purpose: Adds a string to the stack with alignment // // Parameters: str - [in] the CString to add // alignment - [in] the string alignment (one of enum StringAlign) // relative to the frame's rectangle // offset - [in] shrink the bounding rectangle by this amount // clr - [in] sting color // size - [in] vertical size of the string // style - [in] the font style (one of enum FontStyles) // name - [in] Font Family name string // // Returns: index to layer added // int Stack::AddAlignString( CString str, int alignment, SPoint offset, Clr clr, int size, int style, WCHAR* name) { TEXTINFO ti; ::ZeroMemory(&ti, sizeof(TEXTINFO)); memcpy(ti.fname, name, 2*wcslen(name)); ti.fsize = size; ti.fstyle = style; ti.align = alignment; ti.foffset.X = (float)offset.point.X; ti.foffset.Y = (float)offset.point.Y; #ifdef _MBCS // convert the CString to wstring size_t cssize = strlen(str) + 1; size_t wcsize = cssize*sizeof(wchar_t); ti.string.reserve(wcsize); wchar_t *pwstr = (wchar_t*)malloc(wcsize); MultiByteToWideChar(CP_ACP, 0, str, (int)cssize, pwstr, (int)wcsize); ti.string = pwstr; m_Strings.push_back(ti); free(pwstr); #else ti.string = str; m_Strings.push_back(ti); #endif int layer = AddLayer(); m_Layers[layer].LayerType = STRING; m_Layers[layer].strIndex = (int)(m_Strings.size() - 1); m_Layers[layer].clr1 = clr.value; return layer; } //============================================================================= // // AddAlignString() // // Purpose: Adds a string to the stack with alignment // // Parameters: sr - [in] the bounding rectangle // str - [in] the CString to add // alignment - [in] the string alignment (one of enum StringAlign) // relative to the passed rectangle // offset - [in] shrink the bounding rectangle by this amount // clr - [in] sting color // size - [in] vertical size of the string // style - [in] the font style (one of enum FontStyles) // name - [in] Font Family name string // // Returns: index to layer added // int Stack::AddAlignString( SRect sr, CString str, int alignment, SPoint offset, Clr clr, int size, int style, WCHAR* name) { TEXTINFO ti; ::ZeroMemory(&ti, sizeof(TEXTINFO)); memcpy(ti.fname, name, 2*wcslen(name)); ti.fsize = size; ti.fstyle = style; ti.align = alignment; #ifdef _MBCS // convert the CString to wstring size_t cssize = strlen(str) + 1; size_t wcsize = cssize*sizeof(wchar_t); ti.string.reserve(wcsize); wchar_t *pwstr = (wchar_t*)malloc(wcsize); MultiByteToWideChar(CP_ACP, 0, str, (int)cssize, pwstr, (int)wcsize); ti.string = pwstr; m_Strings.push_back(ti); free(pwstr); #else ti.string = str; m_Strings.push_back(ti); #endif int layer = AddLayer(); m_Layers[layer].lrect = sr.rect; m_Layers[layer].LayerType = STRING; m_Layers[layer].strIndex = (int)(m_Strings.size() - 1); m_Layers[layer].clr1 = clr.value; return layer; } //============================================================================= // // AddEffectString() // // Purpose: Adds a string to the stack with alignment // // Parameters: str - [in] the CString to add // offset - [in] shrink the bounding rectangle by this amount // effect = [in] one of enum StringEffects // size - [in] vertical size of the string // style - [in] the font style (one of enum FontStyles) // name - [in] Font Family name string // clr1 - [in] sting face color // clr2 - [in] first effect color // width2 - [in] size of first effect // clr3 - [in] second effect color [optional] - depends on effect // width3 - [in] size of second effect [optional] - depends on effect // // Returns: index to layer added // int Stack::AddEffectString( CString str, SPoint offset, int effect, int size, int style, WCHAR* name, Clr clr1, Clr clr2, int width2, Clr clr3, int width3) { TEXTINFO ti; ::ZeroMemory(&ti, sizeof(TEXTINFO)); memcpy(ti.fname, name, 2*wcslen(name)); ti.fsize = size; ti.fstyle = style; ti.foffset.X = (float)offset.point.X; ti.foffset.Y = (float)offset.point.Y; #ifdef _MBCS // convert the CString to wstring size_t cssize = strlen(str) + 1; size_t wcsize = cssize*sizeof(wchar_t); ti.string.reserve(wcsize); wchar_t *pwstr = (wchar_t*)malloc(wcsize); MultiByteToWideChar(CP_ACP, 0, str, (int)cssize, pwstr, (int)wcsize); ti.string = pwstr; m_Strings.push_back(ti); free(pwstr); #else ti.string = str; m_Strings.push_back(ti); #endif int layer = AddLayer(); //m_Layers[layer].lrect = sr.rect; m_Layers[layer].LayerType = EFFECTSTRING; m_Layers[layer].strIndex = (int)(m_Strings.size() - 1); m_Layers[layer].clr1 = clr1.value; m_Layers[layer].clr2 = clr2.value; m_Layers[layer].clr3 = clr3.value; m_Layers[layer].rParams[0] = (float)effect; m_Layers[layer].rParams[1] = (float)width2; m_Layers[layer].rParams[2] = (float)width3; return layer; } //============================================================================= // // AddEffectString() // // Purpose: Adds a string to the stack with alignment // // Parameters: sr - [in] the bounding rectangle // str - [in] the CString to add // offset - [in] shrink the bounding rectangle by this amount // effect = [in] one of enum StringEffects // size - [in] vertical size of the string // style - [in] the font style (one of enum FontStyles) // name - [in] Font Family name string // clr1 - [in] sting face color // clr2 - [in] first effect color // width2 - [in] size of first effect // clr3 - [in] second effect color [optional] - depends on effect // width3 - [in] size of second effect [optional] - depends on effect // // Returns: index to layer added // int Stack::AddEffectString( SRect sr, CString str, SPoint offset, int effect, int size, int style, WCHAR* name, Clr clr1, Clr clr2, int width2, Clr clr3, int width3) { TEXTINFO ti; ::ZeroMemory(&ti, sizeof(TEXTINFO)); memcpy(ti.fname, name, 2*wcslen(name)); ti.fsize = size; ti.fstyle = style; ti.foffset.X = (float)offset.point.X; ti.foffset.Y = (float)offset.point.Y; #ifdef _MBCS // convert the CString to wstring size_t cssize = strlen(str) + 1; size_t wcsize = cssize*sizeof(wchar_t); ti.string.reserve(wcsize); wchar_t *pwstr = (wchar_t*)malloc(wcsize); MultiByteToWideChar(CP_ACP, 0, str, (int)cssize, pwstr, (int)wcsize); ti.string = pwstr; m_Strings.push_back(ti); free(pwstr); #else ti.string = str; m_Strings.push_back(ti); #endif int layer = AddLayer(); m_Layers[layer].lrect = sr.rect; m_Layers[layer].LayerType = EFFECTSTRING; m_Layers[layer].strIndex = (int)(m_Strings.size() - 1); m_Layers[layer].clr1 = clr1.value; m_Layers[layer].clr2 = clr2.value; m_Layers[layer].clr3 = clr3.value; m_Layers[layer].rParams[0] = (float)effect; m_Layers[layer].rParams[1] = (float)width2; m_Layers[layer].rParams[2] = (float)width3; return layer; } //============================================================================= // // ApplyTransform() // // Purpose: Set the current smoothing mode // // Parameters: xform - [in] one of LayerXForms // // Returns: index to layer added // int Stack::ApplyTransform(int xform) { int layer = AddLayer(); m_Layers[layer].LayerType = APPLYXFORM; m_Layers[layer].gradMode = xform; return layer; }