svvitch
digital signage player
D:/vs_workspace/switch_sf/src/svvitch/TextContent.cpp
Go to the documentation of this file.
00001 #include "TextContent.h"
00002 
00003 #include <Poco/FileStream.h>
00004 #include <Poco/LineEndingConverter.h>
00005 #include <Poco/NumberParser.h>
00006 #include <Poco/RegularExpression.h>
00007 #include <Poco/string.h>
00008 #include <Poco/UnicodeConverter.h>
00009 
00010 #include <gdiplus.h>
00011 
00012 #include "Utils.h"
00013 
00014 using namespace Gdiplus;
00015 
00016 
00017 TextContent::TextContent(Renderer& renderer, int splitType, float x, float y, float w, float h): Content(renderer, splitType, x, y, w, h),
00018     _texture(NULL), _referencedText(NULL), _async(false)
00019 {
00020     initialize();
00021 }
00022 
00023 TextContent::‾TextContent() {
00024     initialize();
00025 }
00026 
00027 void TextContent::initialize() {
00028     Poco::ScopedLock<Poco::FastMutex> lock(_initializeLock);
00029     close();
00030     _dx = 0;
00031     _dy = 0;
00032 }
00033 
00034 bool TextContent::open(const MediaItemPtr media, const int offset) {
00035     initialize();
00036     Poco::RegularExpression re("^(sjis|shift_jis|shiftjis|ms932)$", Poco::RegularExpression::RE_CASELESS + Poco::RegularExpression::RE_EXTENDED);
00037 
00038     bool valid = false;
00039     if (offset != -1 && offset < media->fileCount()) {
00040         MediaItemFile mif =  media->files().at(offset);
00041         if (mif.type() == MediaTypeText) {
00042             _textFont = mif.getProperty("font");
00043             if (_textFont.empty()) _textFont = config().textFont;
00044             _textHeight = mif.getNumProperty("fh", config().textHeight);
00045             _desent = 0;
00046             _c1 = mif.getHexProperty("c1", 0xffffffff);
00047             _c2 = mif.getHexProperty("c2", 0xffcccccc);
00048             _b1 = mif.getHexProperty("b1", 0xff000000);
00049             _b2 = mif.getHexProperty("b2", 0x00cccccc);
00050             _borderSize1 = mif.getFloatProperty("bs1", 4);
00051             _borderSize2 = mif.getFloatProperty("bs2", 0);
00052             _textStyle = mif.getProperty("style", config().textStyle);
00053 
00054             _x = mif.getNumProperty("x", 0);
00055             _y = mif.getNumProperty("y", 0);
00056             _w = mif.getNumProperty("w", config().stageRect.right);
00057             _h = mif.getNumProperty("h", config().stageRect.bottom);
00058             _cx = mif.getNumProperty("cx", _x);
00059             _cy = mif.getNumProperty("cy", _y);
00060             _cw = mif.getNumProperty("cw", _w);
00061             _ch = mif.getNumProperty("ch", _h);
00062             _move = mif.getProperty("move");
00063             _frameWait = mif.getNumProperty("fw", 0);
00064             _async = mif.getProperty("async") == "true";
00065             //_dx = mif.getFloatProperty("dx", F(0));
00066             //_dy = mif.getFloatProperty("dy", F(0));
00067             _align = mif.getProperty("align");
00068             _fitBounds = mif.getProperty("fit") == "true";
00069             string pos = Poco::format("(%0.1hf,%0.1hf) %0.1hfx%0.1hf dx:%0.1hf dy:%0.1hf", _x, _y, _w, _h, _dx, _dy);
00070             pos += Poco::format(" fw:%d", _frameWait);
00071             _log.information(Poco::format("text: [%s] %s", _textFont, pos));
00072 
00073             if (!mif.file().empty() && mif.file().find("$") == string::npos) {
00074                 string text;
00075                 try {
00076                     Poco::RegularExpression::Match m;
00077                     bool isSJIS = re.match(mif.getProperty("encoding"), m);
00078                     Poco::FileInputStream fis(Path(mif.file()).absolute(config().dataRoot).toString(), std::ios::in);
00079                     try {
00080                         Poco::InputLineEndingConverter ilec(fis);
00081                         char line[1024];
00082                         int linenum = 1;
00083                         while (!ilec.eof()) {
00084                             line[0] = '¥0';
00085                             ilec.getline(line, sizeof(line));
00086                             if (!text.empty()) text += "          ";
00087                             if (isSJIS) {
00088                                 // sjis
00089                                 wstring wline;
00090                                 svvitch::sjis_utf16(string(line), wline);
00091                                 string utf8;
00092                                 Poco::UnicodeConverter::toUTF8(wline, utf8);
00093                                 text = Poco::cat(text, utf8);
00094                             } else {
00095                                 // UTF-8
00096                                 text = Poco::cat(text, string(line));
00097                             }
00098                             linenum++;
00099                         }
00100                         _log.information(Poco::format("lines: %d %s", linenum, text));
00101 
00102                         drawTexture(text);
00103                         valid = true;
00104                     } catch (Poco::Exception& ex) {
00105                         _log.warning(Poco::format("I/O error: %s", ex.displayText()));
00106                     }
00107                     fis.close();
00108                 } catch (Poco::PathNotFoundException& ex) {
00109                     _log.warning(Poco::format("file not found: %s", mif.file()));
00110                 } catch (Poco::Exception& ex) {
00111                     _log.warning(Poco::format("failed read text: %s", ex.displayText()));
00112                 }
00113             } else {
00114                 // ファイル指定無し
00115                 _log.information("text template mode");
00116                 valid = true;
00117             }
00118         } else {
00119             _log.warning("failed type error");
00120         }
00121     }
00122 
00123     if (valid) {
00124         _mediaID = media->id();
00125         set("alpha", 1.0f);
00126         return true;
00127     }
00128     return false;
00129 }
00130 
00131 void TextContent::setReference(TextContent* text) {
00132     Poco::ScopedLock<Poco::FastMutex> lock(_lock);
00133     _referencedText = text;
00134     _log.information("set reference text content");
00135 }
00136 
00137 void TextContent::play() {
00138     if (_move.find("roll-left-") == 0) {
00139         _x = _cx + _cw;
00140         _sx = _x;
00141         //_y = 0;
00142         int dx = 0;
00143         Poco::NumberParser::tryParse(_move.substr(10), dx);
00144         _dx = -dx;
00145         _log.debug(Poco::format("move: scroll-left: %0.1hf", _dx));
00146     } else if (_move.find("roll-up-") == 0) {
00147         _y = _cy + _ch;
00148         _sy = _y;
00149         int dy = 0;
00150         Poco::NumberParser::tryParse(_move.substr(8), dy);
00151         _dy = -dy;
00152         _log.debug(Poco::format("move: scroll-up: %0.1hf", _dy));
00153     }
00154     _playing = true;
00155 }
00156 
00157 void TextContent::stop() {
00158     _playing = false;
00159 }
00160 
00161 const bool TextContent::finished() {
00162     Poco::ScopedLock<Poco::FastMutex> lock(_lock);
00163     if (_move.empty() || _async) {
00164         return true;
00165     }
00166     return !_playing;
00167 }
00168 
00170 void TextContent::close() {
00171     _mediaID.clear();
00172     LPDIRECT3DTEXTURE9 old = NULL;
00173     {
00174         Poco::ScopedLock<Poco::FastMutex> lock(_lock);
00175         if (_referencedText) {
00176             _referencedText = NULL;
00177         } else {
00178             old = _texture;
00179         }
00180         _texture = NULL;
00181     }
00182     SAFE_RELEASE(old);
00183     _iw = 0;
00184     _ih = 0;
00185     _tw = 0;
00186     _th = 0;
00187 }
00188 
00190 void TextContent::process(const DWORD& frame) {
00191     if (_align == "center") {
00192         _ax = (_w - _iw) / 2;
00193     } else if (_align == "right") {
00194         _ax = _w - _iw;
00195     } else {
00196         _ax = 0;
00197     }
00198 
00199     {
00200         Poco::ScopedLock<Poco::FastMutex> lock(_lock);
00201         if (_referencedText) {
00202             _texture = _referencedText->_texture;
00203             _ax = _referencedText->_ax;
00204             _iw = _referencedText->_iw;
00205             _ih = _referencedText->_ih;
00206             _tw = _referencedText->_tw;
00207             _th = _referencedText->_th;
00208         }
00209     }
00210     if (!_mediaID.empty() && _texture && _playing) {
00211         if (!_move.empty()) {
00212             if (_frameWait <= 0 || (frame % _frameWait) == 0) {
00213                 _x += _dx;
00214                 _y += _dy;
00215             }
00216             if (!_async) {
00217                 if (_move.find("roll-left-") == 0) {
00218                     if (_dx != 0) {
00219                         _duration = abs((_sx + _iw) / _dx);
00220                         int current = abs((_sx - _x) / _dx);
00221                         int dt = abs((_x - (_cx - _iw)) / _dx);
00222                         const int fps = 60;
00223                         unsigned long cu = current / fps;
00224                         unsigned long re = dt / fps;
00225                         string t1 = Poco::format("%02lu:%02lu:%02lu.%02d", cu / 3600, cu / 60, cu % 60, (current % fps) / 2);
00226                         string t2 = Poco::format("%02lu:%02lu:%02lu.%02d", re / 3600, re / 60, re % 60, (dt % fps) / 2);
00227                         set("time", Poco::format("%s %s", t1, t2));
00228                         set("time_current", t1);
00229                         set("time_remain", t2);
00230                     }
00231                     if (_x < (_cx - _iw)) {
00232                         // _log.information(Poco::format("text move finished: %hf %d %d", _x, _cx, _iw));
00233                         _dx = 0;
00234                         _move.clear();
00235                         //_playing = false;
00236                     }
00237                 } else if (_move.find("roll-up-") == 0) {
00238                     if (_dy != 0) {
00239                         _duration = abs((_sy + _ih) / _dy);
00240                         int current = abs((_sy - _y) / _dy);
00241                         int dt = abs((_y - (_cy - _ih)) / _dy);
00242                         const int fps = 60;
00243                         unsigned long cu = current / fps;
00244                         unsigned long re = dt / fps;
00245                         string t1 = Poco::format("%02lu:%02lu:%02lu.%02d", cu / 3600, cu / 60, cu % 60, (current % fps) / 2);
00246                         string t2 = Poco::format("%02lu:%02lu:%02lu.%02d", re / 3600, re / 60, re % 60, (dt % fps) / 2);
00247                         set("time", Poco::format("%s %s", t1, t2));
00248                         set("time_current", t1);
00249                         set("time_remain", t2);
00250                     }
00251                     if (_y < (_cy - _ih)) {
00252                         _dy = 0;
00253                         _move.clear();
00254                     }
00255                 } else {
00256                     _duration = 0;
00257                 }
00258             } else {
00259                 if (_x < (_cx - _iw)) _x = _cx + _cw;
00260                 _duration = 0;
00261             }
00262         }
00263         //_x+=_dx;
00264         //_y+=_dy;
00265         _current++;
00266         if (_duration < _current) _current = _duration;
00267     }
00268 }
00269 
00271 void TextContent::draw(const DWORD& frame) {
00272     Poco::ScopedLock<Poco::FastMutex> lock(_lock);
00273     if (!_mediaID.empty() && _texture && _playing) {
00274         LPDIRECT3DDEVICE9 device = _renderer.get3DDevice();
00275         float alpha = getF("alpha", 1.0f);
00276         DWORD col = ((DWORD)(0xff * alpha) << 24) | 0xffffff;
00277         int cw = config().splitSize.cx;
00278         int ch = config().splitSize.cy;
00279 
00280         switch (_splitType) {
00281         case 1:
00282             {
00283                 device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
00284                 RECT scissorRect;
00285                 device->GetScissorRect(&scissorRect);
00286                 float x = _x + _ax;
00287                 float y = _y;
00288                 int ix = 0, sx = 0, sy = 0, dx = (int)x / (cw * config().splitCycles) * cw, dxx = (int)fmod(x, cw), dy = ch * ((int)x / cw) % (config().splitCycles * ch);
00289                 int cww = 0;
00290                 int chh = (ch > _ih)?_ih:ch;
00291                 int clipX = _cx;
00292                 while (dx < config().mainRect.right) {
00293                     RECT rect = {dx, dy, dx + cw, dy + chh};
00294                     int cx = dx * config().splitCycles + dy / ch * cw; // cx=実際の映像の横位置
00295                     if (cx > config().stageRect.right) break;
00296                     int cxx = _cx - cx;
00297                     if (cxx > cw) {
00298                         SetRect(&rect, 0, 0, 0, 0);
00299                     } else if (cxx >= 0) {
00300                         SetRect(&rect, dx + cxx, rect.top, rect.right, rect.bottom);
00301                     }
00302                     cxx = _cx + _cw - cx;
00303                     if (cxx < 0) {
00304                         SetRect(&rect, 0, 0, 0, 0);
00305                     } else if (cxx <= cw) {
00306                         SetRect(&rect, rect.left, rect.top, dx + cxx, rect.bottom);
00307                     }
00308                     device->SetScissorRect(&rect);
00309 //                  if ((sx + cw - dxx) >= _tw) {
00310                     if ((sx + cw - dxx) >= _tw) {
00311                         // ソースの横がはみ出る()
00312                         cww = _tw - sx;
00313                         _renderer.drawTexture(dx + dxx, y + dy, cww, chh, sx, sy, cww, chh, _texture, 0, col, col, col, col);
00314                         // _renderer.drawFontTextureText(dx + dxx, y + dy, 10, 10, 0xffff0000, Poco::format("%d,%d %d %d %d %d", sx, sy, cw, dxx, _tw, cww));
00315                         sx = 0;
00316                         sy += _ih;
00317                         if (sy < _th) {
00318                             // srcを折り返してdstの残りに描画
00319                             if (_th - sy < ch) chh = _th - sy;
00320                             _renderer.drawTexture(dx + dxx + cww, y + dy, cw - cww, chh, sx, sy, cw - cww, chh, _texture, 0, col, col, col, col);
00321                             // _renderer.drawFontTextureText(dx + dxx + cww, y + dy, 12, 12, 0xff00ff00, Poco::format("t%d,%d", sx, sy));
00322                             sx += cw - cww;
00323                             ix += cw;
00324                             dxx = cww + cw - cww;
00325 //                          if (ix >= _iw) _log.information(Poco::format("image check1: %d,%d %d", dx, dy, dxx));
00326                         } else {
00327                             // dstの途中でsrcが全て終了
00328                             dxx = _iw - ix;
00329                             ix = _iw;
00330 //                          if (ix >= _iw) _log.information(Poco::format("image check2: %d,%d %d", dx, dy, dxx));
00331                         }
00332                     } else {
00333 
00334                         if (_iw - ix < (cw - dxx)) {
00335                             cww = _iw - ix;
00336                         } else {
00337                             cww = cw - dxx;
00338                         }
00339                         if (sx + cww >= _tw) {
00340                             cww = _tw - sx;
00341                         }
00342                         _renderer.drawTexture(dx + dxx, y + dy, cww, chh, sx, sy, cww, chh, _texture, 0, col, col, col, col);
00343                         // _renderer.drawFontTextureText(dx + dxx, y + dy, 12, 12, 0xffffcc00, Poco::format("%d,%d", sx, sy));
00344                         sx += cww;
00345                         ix += cww;
00346 //                      dxx = cww;
00347                     }
00348                     if (ix >= _iw) {
00349                         break;
00350 //                      dxx = cw - cww;
00351 //                      sx = 0;
00352 //                      ix = 0;
00353                     }
00354                     dxx = 0;
00355                     dy += ch;
00356                     if (dy >= config().splitCycles * ch) {
00357                         dx += cw;
00358                         dy = 0;
00359                     }
00360                 }
00361                 device->SetScissorRect(&scissorRect);
00362             }
00363             break;
00364 
00365         case 2:
00366             {
00367                 device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
00368                 RECT scissorRect;
00369                 device->GetScissorRect(&scissorRect);
00370                 int cww = cw;
00371                 int chh = ch;
00372                 int sw = config().stageRect.right / cw;
00373                 int sh = config().stageRect.bottom / ch;
00374                 for (int sy = 0; sy < sh; sy++) {
00375                     int ox = (sy % 2) * cw * 8 + (L(_y / ch) % 2) * cw * 8 + config().stageRect.left;
00376                     int oy = (sy / 2) * ch * 4 + (L(_y / ch) / 2) * ch * 4 + config().stageRect.top;
00377                     for (int sx = 0; sx < sw; sx++) {
00378 //                      if (_x >= sx * cw + cw || _x + _tw < sx * cw) continue;
00379                         int dx = (sx / 4) * cw;
00380                         int dy = ch * 3 - (sx % 4) * ch;
00381                         RECT rect = {ox + dx, oy + dy, ox + dx + cw, oy + dy + ch};
00382                         device->SetScissorRect(&rect);
00383                         int tx = sx * cw -_x;
00384                         int ty = -_dy; //sy * ch -_y;
00385                         int tcw = cww;
00386                         int tch = chh;
00387                         if (_tw - tx < cww) tcw = _tw - tx;
00388 //                      if (_th - ty < chh) tch = _th - ty;
00389                         if (tcw > 0 && tch > 0) _renderer.drawTexture(ox + dx, oy + dy, tcw, tch, tx, ty, tcw, tch, _texture, 0, col, col, col, col);
00390                     }
00391                 }
00392                 device->SetScissorRect(&scissorRect);
00393 //              _renderer.drawFontTextureText(0, conf->subRect.bottom - 40, 12, 16, 0xffcccccc, Poco::format("text: %d,%d", tx, ty));
00394             }
00395             break;
00396         default:
00397             {
00398                 float alpha = getF("alpha");
00399                 DWORD col = ((DWORD)(0xff * alpha) << 24) | 0xffffff;
00400                 if (_fitBounds) {
00401                     device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
00402                     device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
00403                     _renderer.drawTexture(_x, _y, _w, _ih, _texture, 0, col, col, col, col);
00404                     device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
00405                     device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
00406                 } else {
00407                     if (_ih != _th) {
00408                         const int c = _th / _ih;
00409                         for (int i = 0; i < c; i++) {
00410                             _renderer.drawTexture(_x + _ax + i * _tw, _y, _tw, _ih, 0, i * _ih, _tw, _ih, _texture, 0, col, col, col, col);
00411                         }
00412                     } else {
00413                         _renderer.drawTexture((int)_x + _ax, (int)_y, _texture, 0, col, col, col, col);
00414                     }
00415                 }
00416             }
00417         }
00418     } else {
00419         if (get("prepare") == "true") {
00420             int sy = getF("itemNo") * 20;
00421             DWORD col = 0xccffffff;
00422             _renderer.drawTexture(700, 600 + sy, 324, 20, _texture, 0, col, col, col, col);
00423         }
00424     }
00425 }
00426 
00427 int TextContent::getTextWidth() {
00428     return _iw;
00429 }
00430 
00431 int TextContent::getTextHeight() {
00432     return _ih;
00433 }
00434 
00435 void TextContent::setFitBounds(bool fit) {
00436     _fitBounds = fit;
00437 }
00438 
00439 void TextContent::setColor(DWORD c1, DWORD c2) {
00440     _c1 = c1;
00441     _c2 = c2;
00442 }
00443 
00444 void TextContent::setBorder1(int size, DWORD col) {
00445     _borderSize1 = size;
00446     _b1 = col;
00447 }
00448 
00449 void TextContent::setBorder2(int size, DWORD col) {
00450     _borderSize2 = size;
00451     _b2 = col;
00452 }
00453 
00454 void TextContent::setFont(string font) {
00455     _textFont = font;
00456 }
00457 
00458 void TextContent::setFontHeight(int height, int desent) {
00459     _textHeight = height;
00460     _desent = desent;
00461 }
00462 
00463 void TextContent::setTextStyle(string style) {
00464     _textStyle = style;
00465 }
00466 
00467 void TextContent::setAlign(string align) {
00468     _align = align;
00469 
00470     if (_align == "center") {
00471         _ax = (_w - _iw) / 2;
00472     } else if (_align == "right") {
00473         _ax = _w - _iw;
00474     } else {
00475         _ax = 0;
00476     }
00477     _log.information(Poco::format("align change: %dx%d %dx%d align: %d", _iw, _ih, _tw, _th, _ax));
00478 }
00479 
00480 void TextContent::drawTexture(string text) {
00481     _text = text;
00482     Rect rect(0, 0, 0, 0);
00483     {
00484         Bitmap bitmap(1, 1, PixelFormat32bppARGB);
00485         drawText(text, bitmap, rect);
00486     }
00487     {
00488         int x = rect.X;
00489         int y = rect.Y;
00490         int w = rect.Width;
00491         int h = rect.Height;
00492         rect.Width = w - x;     // rectの領域をx/y=0で作り直す
00493         rect.Height = h - y;    // ただしx/yはクリアせずそのまま引き渡すことで、biasとして使用する
00494         _log.debug(Poco::format("bitmap: %d,%d %dx%d", x, y, w, h));
00495 //      int sh = config().stageRect.bottom;
00496         LPDIRECT3DTEXTURE9 texture = _renderer.createTexture(w, h, D3DFMT_A8R8G8B8);
00497         int tw = 0;
00498         int th = 0;
00499         int iw = 0;
00500         int ih = 0;
00501         if (texture) {
00502             D3DSURFACE_DESC desc;
00503             HRESULT hr = texture->GetLevelDesc(0, &desc);
00504             tw = desc.Width;
00505             th = desc.Height;
00506             _log.information(Poco::format("text texture: %dx%d", tw, th));
00507 //          th = sh;
00508         } else {
00509             // 指定サイズのテクスチャが作れない
00510             tw = config().imageSplitWidth;
00511             th = h;
00512         }
00513         if (w > tw || !texture) {
00514             // テクスチャの幅の方が小さい場合、テクスチャを折返しで作る
00515             SAFE_RELEASE(texture);
00516             Bitmap bitmap(w, h, PixelFormat32bppARGB);
00517             drawText(text, bitmap, rect);
00518             texture = _renderer.createTexture(tw, th * ((w + tw - 1) / tw), D3DFMT_A8R8G8B8);
00519             if (!texture) return;
00520             D3DSURFACE_DESC desc;
00521             HRESULT hr = texture->GetLevelDesc(0, &desc);
00522             _log.information(Poco::format("text texture(with turns %dx%d): %ux%u", tw, th, desc.Width, desc.Height));
00523             _renderer.colorFill(texture, 0x00000000);
00524             D3DLOCKED_RECT lockRect;
00525             hr = texture->LockRect(0, &lockRect, NULL, 0);
00526             if (SUCCEEDED(hr)) {
00527                 Bitmap dst(desc.Width, desc.Height, lockRect.Pitch, PixelFormat32bppARGB, (BYTE*)lockRect.pBits);
00528                 Graphics g(&dst);
00529                 int y = 0;
00530                 for (int x = 0; x < w; x+=tw) {
00531                     Rect rect(0, y, tw, th);
00532                     g.SetClip(rect);
00533                     g.DrawImage(&bitmap, -x, y);
00534                     y += th;
00535                 }
00536                 g.Flush();
00537                 hr = texture->UnlockRect(0);
00538 //              _w = 1024;
00539                 iw = w;
00540                 ih = h;
00541                 tw = desc.Width;
00542                 th = desc.Height;
00543             }
00544 
00545         } else {
00546             // 折返し無し
00547             _renderer.colorFill(texture, 0x00000000);
00548             D3DLOCKED_RECT lockRect;
00549             HRESULT hr = texture->LockRect(0, &lockRect, NULL, 0);
00550             if (SUCCEEDED(hr)) {
00551                 Bitmap bitmap(tw, th, lockRect.Pitch, PixelFormat32bppARGB, (BYTE*)lockRect.pBits);
00552                 drawText(text, bitmap, rect);
00553                 hr = texture->UnlockRect(0);
00554                 _log.information(Poco::format("draw text texture: %dx%d", tw, th));
00555 //              _w = (float)rect.Width;
00556                 iw = tw;
00557                 ih = th;
00558             }
00559         }
00560         LPDIRECT3DTEXTURE9 old = NULL;
00561         {
00562             Poco::ScopedLock<Poco::FastMutex> lock(_lock);
00563             if (_texture) old = _texture;
00564             _texture = texture;
00565             // D3DXSaveTextureToFile(L"test_text.png", D3DXIFF_PNG, _texture, NULL);
00566             _iw = iw;
00567             _ih = ih;
00568             _tw = tw;
00569             _th = th;
00570         }
00571         SAFE_RELEASE(old);
00572     }
00573 
00574     if (_align == "center") {
00575         _ax = (_w - _iw) / 2;
00576     } else if (_align == "right") {
00577         _ax = _w - _iw;
00578     } else {
00579         _ax = 0;
00580     }
00581     _log.information(Poco::format("texture updated: %dx%d %dx%d align: %d", _iw, _ih, _tw, _th, _ax));
00582 }
00583 
00584 void TextContent::drawText(string text, Bitmap& bitmap, Rect& rect) {
00585     int x = 0;
00586     int y = 0;
00587     int h = rect.GetBottom() - rect.GetTop();
00588     if (rect.GetRight() - rect.GetLeft() != 0 || rect.GetBottom() - rect.GetTop() != 0) {
00589         x = -rect.X;
00590         y = -rect.Y;
00591     }
00592 
00593     Graphics g(&bitmap);
00594     g.SetSmoothingMode(SmoothingModeHighQuality);
00595     g.SetTextRenderingHint(TextRenderingHintAntiAlias);
00596 
00597     Gdiplus::FontFamily* ff = NULL;
00598     _renderer.getPrivateFontFamily(_textFont, &ff);
00599     if (!ff) {
00600         // アプリのフォントが利用できない場合システムから取得してみる
00601         std::wstring wfontFamily;
00602         Poco::UnicodeConverter::toUTF16(_textFont, wfontFamily);
00603         Font f(wfontFamily.c_str(), _textHeight);
00604         Gdiplus::FontFamily fontFamily;
00605         f.GetFamily(&fontFamily);
00606         ff = fontFamily.Clone();
00607         WCHAR wname[64] = L"";
00608         ff->GetFamilyName(wname);
00609         string name;
00610         Poco::UnicodeConverter::toUTF8(wname, name);
00611         _log.information(Poco::format("installed font: %s", name));
00612     }
00613     Gdiplus::FontStyle style;
00614     if (_textStyle == "bold") {
00615         style = Gdiplus::FontStyleBold;
00616     } else if (_textStyle == "italic") {
00617         style = Gdiplus::FontStyleItalic;
00618     } else if (_textStyle == "bolditalic") {
00619         style = Gdiplus::FontStyleBoldItalic;
00620     } else {
00621         style = Gdiplus::FontStyleRegular;
00622     }
00623 
00624     Poco::RegularExpression re1("¥¥r|¥¥n");
00625     re1.subst(text, "          ", Poco::RegularExpression::RE_GLOBAL);
00626     std::wstring wtext;
00627     Poco::UnicodeConverter::toUTF16(text, wtext);
00628     size_t len = wcslen(wtext.c_str());
00629     int bh = _borderSize1 + _borderSize2;
00630     GraphicsPath path;
00631     path.AddString(wtext.c_str(), len, ff, style, _textHeight, Point(x, y + bh), StringFormat::GenericDefault());
00632     if (_borderSize2 > F(0)) {
00633         SolidBrush borderBrush2(_b2);
00634         Pen pen2(&borderBrush2, bh);
00635         pen2.SetLineJoin(LineJoinRound);
00636         g.DrawPath(&pen2, &path);
00637     }
00638     SolidBrush borderBrush1(_b1);
00639     Pen pen1(&borderBrush1, _borderSize1);
00640     if (_borderSize1 > F(0)) {
00641         pen1.SetLineJoin(LineJoinRound);
00642         g.DrawPath(&pen1, &path);
00643     }
00644     LinearGradientBrush foreBrush(Rect(0, 0, 1, rect.GetBottom() + rect.GetTop()), _c1, _c2, LinearGradientModeVertical);
00645     g.FillPath(&foreBrush, &path);
00646 
00647     // pen1のサイズでrectを取得
00648     if (_borderSize1 > 0) path.Widen(&pen1);
00649     path.GetBounds(&rect);
00650     if (_borderSize2 > F(0)) {
00651         rect.Height = rect.Height + _borderSize2 * 2;
00652     }
00653     g.Flush();
00654     SAFE_DELETE(ff);
00655 
00656     if (false) {
00657         UINT num;        // number of image encoders
00658         UINT size;       // size, in bytes, of the image encoder array
00659         ImageCodecInfo* pImageCodecInfo;
00660         GetImageEncodersSize(&num, &size);
00661         pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
00662         GetImageEncoders(num, size, pImageCodecInfo);
00663         for (int i = 0; i < num ; i ++) {
00664             if (!wcscmp(pImageCodecInfo[i].MimeType, L"image/png")) {
00665                 bitmap.Save(L"test.png", &pImageCodecInfo[i].Clsid);
00666                 break;
00667             }
00668         }
00669         free(pImageCodecInfo);
00670     }
00671 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines