CslBloodFrontier::CslBloodFrontier() { m_name=CSL_DEFAULT_NAME_BF; m_defaultMasterConnection=CslMasterConnection(CSL_DEFAULT_MASTER_BF,CSL_DEFAULT_MASTER_PORT_BF); m_capabilities=CSL_CAPABILITY_EXTINFO | CSL_CAPABILITY_CUSTOM_CONFIG | CSL_CAPABILITY_CONNECT_PASS | CSL_CAPABILITY_CONNECT_ADMIN_PASS; #ifdef __WXMAC__ m_clientSettings.ConfigPath=::wxGetHomeDir(); m_clientSettings.ConfigPath<<wxT("/Library/Application Support/bloodfrontier"); #elif __WXGTK__ m_clientSettings.ConfigPath=::wxGetHomeDir()+wxT("/.bloodfrontier"); #endif m_icon16=BitmapFromData(wxBITMAP_TYPE_PNG,bf_16_png,sizeof(bf_16_png)); m_icon24=BitmapFromData(wxBITMAP_TYPE_PNG,bf_24_png,sizeof(bf_24_png)); }
CslGameRedEclipse::CslGameRedEclipse() { m_name=CSL_DEFAULT_NAME_RE; m_defaultMasterConnection=CslMasterConnection(CSL_DEFAULT_MASTER_RE,CSL_DEFAULT_MASTER_PORT_RE); m_capabilities=CSL_CAPABILITY_EXTINFO | CSL_CAPABILITY_CUSTOM_CONFIG | CSL_CAPABILITY_CONNECT_PASS | CSL_CAPABILITY_CONNECT_ADMIN_PASS; #ifdef __WXMAC__ m_clientSettings.ConfigPath=::wxGetHomeDir(); m_clientSettings.ConfigPath<<wxT("/Library/Application Support/redeclipse"); #elif __WXGTK__ m_clientSettings.ConfigPath=::wxGetHomeDir()+wxT("/.redeclipse"); #endif m_icon16=BitmapFromData(wxBITMAP_TYPE_PNG,re_16_png,sizeof(re_16_png)); m_icon24=BitmapFromData(wxBITMAP_TYPE_PNG,re_24_png,sizeof(re_24_png)); }
static RenderedBitmap *ThumbFromCoverPage(Doc doc, SizeI size) { ImageData *coverImage = doc.GetCoverImage(); if (!coverImage) return nullptr; Bitmap *coverBmp = BitmapFromData(coverImage->data, coverImage->len); if (!coverBmp) return nullptr; Bitmap res(size.dx, size.dy, PixelFormat24bppRGB); float scale = (float)size.dx / (float)coverBmp->GetWidth(); int fromDy = size.dy; if (scale < 1.f) fromDy = (int)((float)coverBmp->GetHeight() * scale); Graphics g(&res); g.SetInterpolationMode(InterpolationModeHighQualityBicubic); Status ok = g.DrawImage(coverBmp, Rect(0, 0, size.dx, size.dy), 0, 0, coverBmp->GetWidth(), fromDy, UnitPixel); if (ok != Ok) { delete coverBmp; return nullptr; } HBITMAP hbmp; ok = res.GetHBITMAP((ARGB)Color::White, &hbmp); delete coverBmp; if (ok == Ok) return new RenderedBitmap(hbmp, SizeI(size.dx, size.dy)); return nullptr; }
void CslPanelAboutImage::OnPaint(wxPaintEvent& event) { static const wxBitmap bmp = BitmapFromData(wxBITMAP_TYPE_PNG,csl_256_png); wxPaintDC dc(this); PrepareDC(dc); dc.DrawBitmap(bmp,0,0,true); event.Skip(); }
static RenderedBitmap* LoadRenderedBitmap(const WCHAR* filePath) { OwnedData data(file::ReadFile(filePath)); if (!data.data) { return nullptr; } Bitmap* bmp = BitmapFromData(data.data, data.size); if (!bmp) { return nullptr; } HBITMAP hbmp; RenderedBitmap* rendered = nullptr; if (bmp->GetHBITMAP((ARGB)Color::White, &hbmp) == Ok) { rendered = new RenderedBitmap(hbmp, SizeI(bmp->GetWidth(), bmp->GetHeight())); } delete bmp; return rendered; }
/* * ReadBitmapFromData */ BOOL ReadBitmapFromData( void *data, char *fullname, WRInfo *info, WResLangNode *lnode ) { bitmap_info bmi; HBITMAP hbitmap; HCURSOR prevcursor; BOOL ret; prevcursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) ); hbitmap = BitmapFromData( data, &bmi ); SetCursor( prevcursor ); if( hbitmap == (HBITMAP)NULL ) { WImgEditError( WIE_ERR_BAD_BITMAP_DATA, fullname ); return( FALSE ); } ret = doReadInBitmapFile( hbitmap, &bmi, fullname, info, lnode ); if( ret ) { SetupMenuAfterOpen(); } return( ret ); } /* ReadBitmapFromData */
const WCHAR *ext = GfxFileExtFromData(data, len); if (str::Eq(ext, L".jpg") || str::Eq(ext, L".jp2")) { Size size = BitmapSizeFromData(data, len); fz_image *image = nullptr; fz_try(ctx) { image = (str::Eq(ext, L".jpg") ? pack_jpeg : pack_jp2)(ctx, data, len, SizeI(size.Width, size.Height)); } fz_catch(ctx) { return false; } bool ok = AddImagePage(image, imgDpi); fz_drop_image(ctx, image); return ok; } Bitmap *bmp = BitmapFromData(data, len); if (!bmp) return false; bool ok = AddImagePage(bmp, imgDpi); delete bmp; return ok; } static bool Is7BitAscii(const WCHAR *str) { for (const WCHAR *c = str; *c; c++) { if (*c < 32 || *c > 127) return false; } return true; }
// adapted from http://cpansearch.perl.org/src/RJRAY/Image-Size-3.230/lib/Image/Size.pm Size BitmapSizeFromData(const char *data, size_t len) { Size result; ByteReader r(data, len); switch (GfxFormatFromData(data, len)) { case Img_BMP: if (len >= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)) { BITMAPINFOHEADER bmi; bool ok = r.UnpackLE(&bmi, sizeof(bmi), "3d2w6d", sizeof(BITMAPFILEHEADER)); CrashIf(!ok); result.Width = bmi.biWidth; result.Height = bmi.biHeight; } break; case Img_GIF: if (len >= 13) { // find the first image's actual size instead of using the // "logical screen" size which is sometimes too large size_t ix = 13; // skip the global color table if ((r.Byte(10) & 0x80)) ix += 3 * (1 << ((r.Byte(10) & 0x07) + 1)); while (ix + 8 < len) { if (r.Byte(ix) == 0x2C) { result.Width = r.WordLE(ix + 5); result.Height = r.WordLE(ix + 7); break; } else if (r.Byte(ix) == 0x21 && r.Byte(ix + 1) == 0xF9) ix += 8; else if (r.Byte(ix) == 0x21 && r.Byte(ix + 1) == 0xFE) { const char *commentEnd = r.Find(ix + 2, 0x00); ix = commentEnd ? commentEnd - data + 1 : len; } else if (r.Byte(ix) == 0x21 && r.Byte(ix + 1) == 0x01 && ix + 15 < len) { const char *textDataEnd = r.Find(ix + 15, 0x00); ix = textDataEnd ? textDataEnd - data + 1 : len; } else if (r.Byte(ix) == 0x21 && r.Byte(ix + 1) == 0xFF && ix + 14 < len) { const char *applicationDataEnd = r.Find(ix + 14, 0x00); ix = applicationDataEnd ? applicationDataEnd - data + 1 : len; } else break; } } break; case Img_JPEG: // find the last start of frame marker for non-differential Huffman/arithmetic coding for (size_t ix = 2; ix + 9 < len && r.Byte(ix) == 0xFF; ) { if (0xC0 <= r.Byte(ix + 1) && r.Byte(ix + 1) <= 0xC3 || 0xC9 <= r.Byte(ix + 1) && r.Byte(ix + 1) <= 0xCB) { result.Width = r.WordBE(ix + 7); result.Height = r.WordBE(ix + 5); } ix += r.WordBE(ix + 2) + 2; } break; case Img_JXR: case Img_TIFF: if (len >= 10) { bool isBE = r.Byte(0) == 'M', isJXR = r.Byte(2) == 0xBC; CrashIf(!isBE && r.Byte(0) != 'I' || isJXR && isBE); const WORD WIDTH = isJXR ? 0xBC80 : 0x0100, HEIGHT = isJXR ? 0xBC81 : 0x0101; size_t idx = r.DWord(4, isBE); WORD count = idx <= len - 2 ? r.Word(idx, isBE) : 0; for (idx += 2; count > 0 && idx <= len - 12; count--, idx += 12) { WORD tag = r.Word(idx, isBE), type = r.Word(idx + 2, isBE); if (r.DWord(idx + 4, isBE) != 1) continue; else if (WIDTH == tag && 4 == type) result.Width = r.DWord(idx + 8, isBE); else if (WIDTH == tag && 3 == type) result.Width = r.Word(idx + 8, isBE); else if (WIDTH == tag && 1 == type) result.Width = r.Byte(idx + 8); else if (HEIGHT == tag && 4 == type) result.Height = r.DWord(idx + 8, isBE); else if (HEIGHT == tag && 3 == type) result.Height = r.Word(idx + 8, isBE); else if (HEIGHT == tag && 1 == type) result.Height = r.Byte(idx + 8); } } break; case Img_PNG: if (len >= 24 && str::StartsWith(data + 12, "IHDR")) { result.Width = r.DWordBE(16); result.Height = r.DWordBE(20); } break; case Img_TGA: if (len >= 16) { result.Width = r.WordLE(12); result.Height = r.WordLE(14); } break; case Img_WebP: if (len >= 30 && str::StartsWith(data + 12, "VP8 ")) { result.Width = r.WordLE(26) & 0x3fff; result.Height = r.WordLE(28) & 0x3fff; } else { result = webp::SizeFromData(data, len); } break; case Img_JP2: if (len >= 32) { size_t ix = 0; while (ix < len - 32) { uint32_t lbox = r.DWordBE(ix); uint32_t tbox = r.DWordBE(ix + 4); if (0x6A703268 /* jp2h */ == tbox) { ix += 8; if (r.DWordBE(ix) == 24 && r.DWordBE(ix + 4) == 0x69686472 /* ihdr */) { result.Width = r.DWordBE(ix + 16); result.Height = r.DWordBE(ix + 12); } break; } else if (lbox != 0 && ix < UINT32_MAX - lbox) { ix += lbox; } else { break; } } } break; } if (result.Empty()) { // let GDI+ extract the image size if we've failed // (currently happens for animated GIF) Bitmap *bmp = BitmapFromData(data, len); if (bmp) result = Size(bmp->GetWidth(), bmp->GetHeight()); delete bmp; } return result; }
// TODO: draw link in the appropriate format (blue text, underlined, should show hand cursor when // mouse is over a link. There's a slight complication here: we only get explicit information about // strings, not about the whitespace and we should underline the whitespace as well. Also the text // should be underlined at a baseline void DrawHtmlPage(Graphics* g, mui::ITextRender* textDraw, Vec<DrawInstr>* drawInstructions, REAL offX, REAL offY, bool showBbox, Color textColor, bool* abortCookie) { Pen debugPen(Color(255, 0, 0), 1); // Pen linePen(Color(0, 0, 0), 2.f); Pen linePen(Color(0x5F, 0x4B, 0x32), 2.f); WCHAR buf[512]; // GDI text rendering suffers terribly if we call GetHDC()/ReleaseHDC() around every // draw, so first draw text and then paint everything else textDraw->SetTextColor(textColor); Status status = Ok; Timer t; textDraw->Lock(); for (DrawInstr& i : *drawInstructions) { RectF bbox = i.bbox; bbox.X += offX; bbox.Y += offY; if (InstrString == i.type || InstrRtlString == i.type) { size_t strLen = str::Utf8ToWcharBuf(i.str.s, i.str.len, buf, dimof(buf)); // soft hyphens should not be displayed strLen -= str::RemoveChars(buf, L"\xad"); textDraw->Draw(buf, strLen, bbox, InstrRtlString == i.type); } else if (InstrSetFont == i.type) { textDraw->SetFont(i.font); } if (abortCookie && *abortCookie) break; } textDraw->Unlock(); double dur = t.Stop(); lf("DrawHtmlPage: textDraw %.2f ms", dur); for (DrawInstr& i : *drawInstructions) { RectF bbox = i.bbox; bbox.X += offX; bbox.Y += offY; if (InstrLine == i.type) { // hr is a line drawn in the middle of bounding box REAL y = floorf(bbox.Y + bbox.Height / 2.f + 0.5f); PointF p1(bbox.X, y); PointF p2(bbox.X + bbox.Width, y); if (showBbox) { status = g->DrawRectangle(&debugPen, bbox); CrashIf(status != Ok); } status = g->DrawLine(&linePen, p1, p2); CrashIf(status != Ok); } else if (InstrImage == i.type) { // TODO: cache the bitmap somewhere (?) Bitmap* bmp = BitmapFromData(i.img.data, i.img.len); if (bmp) { status = g->DrawImage(bmp, bbox, 0, 0, (REAL)bmp->GetWidth(), (REAL)bmp->GetHeight(), UnitPixel); // GDI+ sometimes seems to succeed in loading an image because it lazily decodes it CrashIf(status != Ok && status != Win32Error); } delete bmp; } else if (InstrLinkStart == i.type) { // TODO: set text color to blue REAL y = floorf(bbox.Y + bbox.Height + 0.5f); PointF p1(bbox.X, y); PointF p2(bbox.X + bbox.Width, y); Pen linkPen(textColor); status = g->DrawLine(&linkPen, p1, p2); CrashIf(status != Ok); } else if (InstrString == i.type || InstrRtlString == i.type) { if (showBbox) { status = g->DrawRectangle(&debugPen, bbox); CrashIf(status != Ok); } } else if (InstrLinkEnd == i.type) { // TODO: set text color back again } else if ((InstrElasticSpace == i.type) || (InstrFixedSpace == i.type) || (InstrString == i.type) || (InstrRtlString == i.type) || (InstrSetFont == i.type) || (InstrAnchor == i.type)) { // ignore } else { CrashIf(true); } if (abortCookie && *abortCookie) break; } }