示例#1
0
void Font::initGDIFont()
{
    if (!m_platformData.size()) {
        m_fontMetrics.reset();
        m_avgCharWidth = 0;
        m_maxCharWidth = 0;
        return;
    }

    HWndDC hdc(0);
    HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());
    OUTLINETEXTMETRIC metrics;
    GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
    TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
    float ascent = textMetrics.tmAscent;
    float descent = textMetrics.tmDescent;
    float lineGap = textMetrics.tmExternalLeading;
    m_fontMetrics.setAscent(ascent);
    m_fontMetrics.setDescent(descent);
    m_fontMetrics.setLineGap(lineGap);
    m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
    m_avgCharWidth = textMetrics.tmAveCharWidth;
    m_maxCharWidth = textMetrics.tmMaxCharWidth;
    float xHeight = ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
    GLYPHMETRICS gm;
    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
    DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &identity);
    if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
        xHeight = gm.gmptGlyphOrigin.y;
    m_fontMetrics.setXHeight(xHeight);
    m_fontMetrics.setUnitsPerEm(metrics.otmEMSquare);

    SelectObject(hdc, oldFont);
}
示例#2
0
int main(int argc, char **argv)
{
    Py_Initialize();
    PyImport_AppendInittab("spam", &PyInit_spam);

    PyRun_SimpleString("from time import time,ctime\n"
                       "print('Today is', ctime(time()))\n");
    PyRun_SimpleString("import spam\n"
                       "xx = spam.SpamCall('abcd')\n"
                       "print(xx)\n");
    PyRun_SimpleString("with open('stackless.py') as ss: exec(ss.read())");
    Py_Finalize();

    ObjectPtrTable::Instance()->Init(10);
    
    TestObj stack_obj;
    TestObj *p_obj = new TestObj;
    ObjectHandler<TestObj> hda(stack_obj);
    ObjectHandler<TestObj> hdb(*p_obj);
    TestObj *stack_obj_ptr = hda.ToObject();
    TestObj *heap_obj_ptr = hdb.ToObject();
    delete p_obj;
    p_obj = new TestObj;
    ObjectHandler<TestObj> hdc(*p_obj);
    heap_obj_ptr = hdb.ToObject();
    if (hdc == hdb) {
        return false;
    }
    else {
        TestObj *heap_obj_ptr_c = hdc.ToObject();
    }
    return 0;
}
示例#3
0
// Return the height of system font |font| in pixels.  We use this size by
// default for some non-form-control elements.
static float systemFontSize(const LOGFONT& font)
{
    float size = -font.lfHeight;
    if (size < 0) {
        HFONT hFont = CreateFontIndirect(&font);
        if (hFont) {
            HWndDC hdc(0); // What about printing? Is this the right DC?
            if (hdc) {
                HGDIOBJ hObject = SelectObject(hdc, hFont);
                TEXTMETRIC tm;
                GetTextMetrics(hdc, &tm);
                SelectObject(hdc, hObject);
                size = tm.tmAscent;
            }
            DeleteObject(hFont);
        }
    }

    // The "codepage 936" bit here is from Gecko; apparently this helps make
    // fonts more legible in Simplified Chinese where the default font size is
    // too small.
    //
    // FIXME: http://b/1119883 Since this is only used for "small caption",
    // "menu", and "status bar" objects, I'm not sure how much this even
    // matters.  Plus the Gecko patch went in back in 2002, and maybe this
    // isn't even relevant anymore.  We should investigate whether this should
    // be removed, or perhaps broadened to be "any CJK locale".
    //
    return ((size < 12.0f) && (GetACP() == 936)) ? 12.0f : size;
}
示例#4
0
FontPlatformData::FontPlatformData(GDIObject<HFONT> font, float size, bool bold, bool oblique, bool useGDI)
    : m_font(SharedGDIObject<HFONT>::create(WTFMove(font)))
    , m_size(size)
    , m_orientation(Horizontal)
    , m_widthVariant(RegularWidth)
    , m_isColorBitmapFont(false)
    , m_syntheticBold(bold)
    , m_syntheticOblique(oblique)
    , m_useGDI(useGDI)
{
    HWndDC hdc(0);
    SaveDC(hdc);
    
    ::SelectObject(hdc, m_font->get());
    UINT bufferSize = GetOutlineTextMetrics(hdc, 0, NULL);

    ASSERT_WITH_MESSAGE(bufferSize, "Bitmap fonts not supported with CoreGraphics.");

    if (bufferSize) {
        OUTLINETEXTMETRICW* metrics = (OUTLINETEXTMETRICW*)malloc(bufferSize);

        GetOutlineTextMetricsW(hdc, bufferSize, metrics);
        WCHAR* faceName = (WCHAR*)((uintptr_t)metrics + (uintptr_t)metrics->otmpFaceName);

        platformDataInit(m_font->get(), size, hdc, faceName);

        free(metrics);
    }

    RestoreDC(hdc, -1);
}
示例#5
0
void CMFC_DemoView::OnDraw(CDC* pDC)
{
	CMFC_DemoDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	CClientDC hdc(this);
	SetMapMode(hdc, MM_ANISOTROPIC);       //设置映像模式
	HPEN hP = (HPEN)GetStockObject(BLACK_PEN);	//黑色画笔
	HBRUSH hB = (HBRUSH)GetStockObject(DKGRAY_BRUSH); //画刷
	SelectObject(hdc, hB);   //选择画刷
	SelectObject(hdc, hP);       //选择画笔
	RoundRect(hdc, 50, 120, 100, 200, 15, 15); //绘制圆角矩形
	hB = (HBRUSH)GetStockObject(LTGRAY_BRUSH);  //采用亮灰色画刷
	SelectObject(hdc, hB);  	   //选择画刷
	Ellipse(hdc, 150, 50, 200, 150); 	   //绘制椭圆
	hB = (HBRUSH)GetStockObject(HOLLOW_BRUSH); //虚画刷
	SelectObject(hdc, hB);  	  //选择画刷
	Pie(hdc, 250, 50, 300, 100, 250, 50, 300, 50);  	//绘制饼形

	hP = CreatePen(PS_DASHDOT, 1, RGB(0, 0, 255));
	hB = CreateHatchBrush(HS_HORIZONTAL, RGB(0, 255, 0));
	SelectObject(hdc, hP);
	SelectObject(hdc, hB);
	RoundRect(hdc, 35, 220, 115, 270, 15, 15);
	Ellipse(hdc, 125, 170, 225, 220);
	Pie(hdc, 250, 120, 300, 170, 300, 120, 300, 170);

}
void display_number_t::measure_vertical(extents_t& calculated_horizontal, const place_data_t& placed_horizontal)
{
    assert(window_m);

    place_data_t save_bounds;
    implementation::get_control_bounds(window_m, save_bounds);

    place_data_t static_bounds;

    top(static_bounds) = top(placed_horizontal);
    left(static_bounds) = left(placed_horizontal);
    width(static_bounds) = width(placed_horizontal);
    height(static_bounds) = 10000; // bottomless

    implementation::set_control_bounds(window_m, static_bounds);

	HDC hdc(::GetWindowDC(window_m));
    std::string title(implementation::get_window_title(window_m));

    std::wstring wtitle;
    to_utf16(title.begin(), title.end(), std::back_inserter(wtitle));
    place_data_liukahr_t out_extent;

//    metrics::set_theme_name(L"Edit");
    //
    // If we don't have the type of this widget, then we should return a
    // zero sized rectangle. This is usually correct, and a good assumption
    // anyway.
    //
    int uxtheme_type = EP_EDITTEXT;
    //
    // Get the text metrics (and calculate the baseline of this widget)
    //
    TEXTMETRIC widget_tm;
    bool have_tm = metrics::get_font_metrics(uxtheme_type, widget_tm);

    assert(have_tm);

    const place_data_liukahr_t in_extents = static_bounds;

    bool have_extents = metrics::get_text_extents(uxtheme_type,
        wtitle.c_str(), out_extent, &in_extents);

    assert(have_extents);

    extents_t::slice_t& vert = calculated_horizontal.vertical();
    vert.length_m = height(out_extent);
    // set the baseline for the text

    metrics::set_window(window_m);

    if (have_tm)
        // distance from top to baseline
        vert.guide_set_m.push_back(widget_tm.tmHeight - widget_tm.tmDescent);

    implementation::set_control_bounds(window_m, save_bounds);
}
示例#7
0
static bool fontContainsCharacter(const FontPlatformData* fontData,
                                  const wchar_t* family, UChar32 character)
{
    // FIXME: For non-BMP characters, GetFontUnicodeRanges is of
    // no use. We have to read directly from the cmap table of a font.
    // Return true for now.
    if (character > 0xFFFF)
        return true;

    // This cache is just leaked on shutdown.
    static FontCmapCache* fontCmapCache = 0;
    if (!fontCmapCache)
        fontCmapCache = new FontCmapCache;

    HashMap<const wchar_t*, icu::UnicodeSet*>::iterator it = fontCmapCache->find(family);
    if (it != fontCmapCache->end())
        return it->value->contains(character);

    HFONT hfont = fontData->hfont();
    HWndDC hdc(0);
    HGDIOBJ oldFont = static_cast<HFONT>(SelectObject(hdc, hfont));
    int count = GetFontUnicodeRanges(hdc, 0);
    if (!count && FontPlatformData::ensureFontLoaded(hfont))
        count = GetFontUnicodeRanges(hdc, 0);
    if (!count) {
        WTF_LOG_ERROR("Unable to get the font unicode range after second attempt");
        SelectObject(hdc, oldFont);
        return true;
    }

    static Vector<char, 512>* gGlyphsetBuffer = 0;
    if (!gGlyphsetBuffer)
        gGlyphsetBuffer = new Vector<char, 512>();
    gGlyphsetBuffer->resize(GetFontUnicodeRanges(hdc, 0));
    GLYPHSET* glyphset = reinterpret_cast<GLYPHSET*>(gGlyphsetBuffer->data());
    // In addition, refering to the OS/2 table and converting the codepage list
    // to the coverage map might be faster.
    count = GetFontUnicodeRanges(hdc, glyphset);
    ASSERT(count > 0);
    SelectObject(hdc, oldFont);

    // FIXME: consider doing either of the following two:
    // 1) port back ICU 4.0's faster look-up code for UnicodeSet
    // 2) port Mozilla's CompressedCharMap or gfxSparseBitset
    unsigned i = 0;
    icu::UnicodeSet* cmap = new icu::UnicodeSet;
    while (i < glyphset->cRanges) {
        WCHAR start = glyphset->ranges[i].wcLow;
        cmap->add(start, start + glyphset->ranges[i].cGlyphs - 1);
        i++;
    }
    cmap->freeze();
    // We don't lowercase |family| because all of them are under our control
    // and they're already lowercased.
    fontCmapCache->set(family, cmap);
    return cmap->contains(character);
}
示例#8
0
// This application exists to be connected to a console session while doing exactly nothing.
// This keeps a console session alive and doesn't interfere with tests or other hooks.
int __cdecl wmain(int /*argc*/, WCHAR* /*argv[]*/)
{
    wil::unique_hdc hdc(CreateCompatibleDC(nullptr));
    RETURN_LAST_ERROR_IF_NULL(hdc);

    LOGFONTW LogFont = { 0 };
    LogFont.lfCharSet = DEFAULT_CHARSET;
    wcscpy_s(LogFont.lfFaceName, L"Terminal");

    EnumFontFamiliesExW(hdc.get(), &LogFont, (FONTENUMPROC)FontEnumForV2Console, (LPARAM)hdc.get(), 0);

    return 0;
}
示例#9
0
LRESULT CFloatingWnd::OnPaint(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL& bHandled){
	CPaintDC hdc(m_hWnd);
	CDC dcMem;
	dcMem.CreateCompatibleDC(hdc);
	hdc.SaveDC();
	dcMem.SaveDC();
	//select and draw
	dcMem.SelectBitmap(m_bmpBackground);
	hdc.BitBlt(0,0,m_size.cx,m_size.cy,dcMem,0,0,SRCCOPY);
	dcMem.RestoreDC(-1);
	hdc.RestoreDC(-1);
	return 0;
}
示例#10
0
// Converts |points| to pixels.  One point is 1/72 of an inch.
static float pointsToPixels(float points)
{
    static float pixelsPerInch = 0.0f;
    if (!pixelsPerInch) {
        HWndDC hdc(0); // What about printing? Is this the right DC?
        if (hdc) // Can this ever actually be NULL?
            pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY);
        else
            pixelsPerInch = 96.0f;
    }

    static const float pointsPerInch = 72.0f;
    return points / pointsPerInch * pixelsPerInch;
}
示例#11
0
void CSVPDialog::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	CRect rcClient;
	GetClientRect(&rcClient);
	CMemoryDC hdc(&dc, rcClient);
	hdc.FillSolidRect(rcClient, m_bgColor);

	CRect rc;
	GetWindowRect(&rc);
	rc-=rc.TopLeft();
	hdc.FrameRgn(&m_rgnBorder, &m_brushBorder,1,1);

}
示例#12
0
FloatRect Font::boundsForGDIGlyph(Glyph glyph) const
{
    HWndDC hdc(0);
    SetGraphicsMode(hdc, GM_ADVANCED);
    HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());

    GLYPHMETRICS gdiMetrics;
    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
    GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gdiMetrics, 0, 0, &identity);

    SelectObject(hdc, oldFont);

    return FloatRect(gdiMetrics.gmptGlyphOrigin.x, -gdiMetrics.gmptGlyphOrigin.y,
        gdiMetrics.gmBlackBoxX + m_syntheticBoldOffset, gdiMetrics.gmBlackBoxY); 
}
示例#13
0
float Font::widthForGDIGlyph(Glyph glyph) const
{
    HWndDC hdc(0);
    SetGraphicsMode(hdc, GM_ADVANCED);
    HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());

    GLYPHMETRICS gdiMetrics;
    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
    GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gdiMetrics, 0, 0, &identity);
    float result = gdiMetrics.gmCellIncX + m_syntheticBoldOffset;

    SelectObject(hdc, oldFont);

    return result;
}
示例#14
0
void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks)
{
    HWndDC hdc(0);

    LOGFONT logFont;
    logFont.lfCharSet = DEFAULT_CHARSET;
    unsigned familyLength = min(familyName.length(), static_cast<unsigned>(LF_FACESIZE - 1));
    memcpy(logFont.lfFaceName, familyName.characters(), familyLength * sizeof(UChar));
    logFont.lfFaceName[familyLength] = 0;
    logFont.lfPitchAndFamily = 0;

    TraitsInFamilyProcData procData(familyName);
    EnumFontFamiliesEx(hdc, &logFont, traitsInFamilyEnumProc, reinterpret_cast<LPARAM>(&procData), 0);
    copyToVector(procData.m_traitsMasks, traitsMasks);
}
示例#15
0
PassRefPtr<SharedBuffer> FontPlatformData::openTypeTable(uint32_t table) const
{
    HWndDC hdc(0);
    HGDIOBJ oldFont = SelectObject(hdc, hfont());

    DWORD size = GetFontData(hdc, table, 0, 0, 0);
    RefPtr<SharedBuffer> buffer;
    if (size != GDI_ERROR) {
        buffer = SharedBuffer::create(size);
        DWORD result = GetFontData(hdc, table, 0, (PVOID)buffer->data(), size);
        ASSERT(result == size);
    }

    SelectObject(hdc, oldFont);
    return buffer.release();
}
示例#16
0
static void OnPaint(HWND hwnd)
{
	CRect r;
	CPaintDC hdc(hwnd);
	CWindow wnd(hwnd);
	wnd.GetClientRect(&r);
	HPEN hPen=CreatePen(PS_SOLID,0,config_bcolor2);
	LOGBRUSH lb={BS_SOLID,config_bcolor1};
	HBRUSH hBrush=CreateBrushIndirect(&lb);

	HPEN hOldPen=hdc.SelectPen(hPen);
	HBRUSH hOldBrush=hdc.SelectBrush(hBrush);
	hdc.Rectangle(&r);
	hdc.SelectPen(hOldPen);
	hdc.SelectBrush(hOldBrush);
	DeleteObject(hPen);
	DeleteObject(hBrush);
}
示例#17
0
// Draws the Mandelbrot set
void DrawSet(HWND hWnd)
{
    // Get client area dimensions, which will be the image size
    RECT rect;
    GetClientRect(hWnd, &rect);
    int imageHeight(rect.bottom);
    int imageWidth(rect.right);

    // Create bitmap for one row of pixels in image
    HDC hdc(GetDC(hWnd));                  // Get device context
    HDC memDC = CreateCompatibleDC(hdc);   // Get device context to draw pixels
    HBITMAP bmp = CreateCompatibleBitmap(hdc, imageWidth, 1);
    HGDIOBJ oldBmp = SelectObject(memDC, bmp);   // Selct bitmap into DC

    // Client area axes
    const double realMin(-2.1);       // Minimum real value
    double imaginaryMin(-1.3);        // Minimum imaginary value
    double imaginaryMax(+1.3);        // Maximum imaginary value

    // Set maximum imaginary so axes are the same scale
    double realMax(realMin + (imaginaryMax - imaginaryMin)*imageWidth / imageHeight);

    // Get scale factors to convert pixel coordinates
    double realScale((realMax - realMin) / (imageWidth - 1));
    double imaginaryScale((imaginaryMax - imaginaryMin) / (imageHeight - 1));

    double cReal(0.0), cImaginary(0.0);   // Stores c components
    double zReal(0.0), zImaginary(0.0);   // Stores z components

    for (int y = 0 ; y < imageHeight ; ++y) {          // Iterate over image rows
        zImaginary = cImaginary = imaginaryMax - y * imaginaryScale;
        for (int x = 0 ; x < imageWidth ; ++x) {         // Iterate over pixels in a row
            zReal = cReal = realMin + x * realScale;
            // Set current pixel color based on n
            SetPixel(memDC, x, 0, Color(IteratePoint(zReal, zImaginary, cReal, cImaginary)));
        }
        // Transfer pixel row to client area device context
        BitBlt(hdc, 0, y, imageWidth, 1, memDC, 0, 0, SRCCOPY);
    }
    SelectObject(memDC, oldBmp);
    DeleteObject(bmp);                       // Delete bitmap
    DeleteDC(memDC);                         // and our working DC
    ReleaseDC(hWnd, hdc);                    // Release client area DC
}
示例#18
0
void Font::initGDIFont()
{
    if (!m_platformData.size()) {
        m_fontMetrics.reset();
        m_avgCharWidth = 0;
        m_maxCharWidth = 0;
        return;
    }

    HWndDC hdc(0);
    HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());
    OUTLINETEXTMETRIC metrics;
    GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
    TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
    float ascent, descent, lineGap;
    // The Open Font Format describes the OS/2 USE_TYPO_METRICS flag as follows:
    // "If set, it is strongly recommended to use OS/2.sTypoAscender - OS/2.sTypoDescender+ OS/2.sTypoLineGap as a value for default line spacing for this font."
    const UINT useTypoMetricsMask = 1 << 7;
    if (metrics.otmfsSelection & useTypoMetricsMask) {
        ascent = metrics.otmAscent;
        descent = metrics.otmDescent;
        lineGap = metrics.otmLineGap;
    } else {
        ascent = textMetrics.tmAscent;
        descent = textMetrics.tmDescent;
        lineGap = textMetrics.tmExternalLeading;
    }
    m_fontMetrics.setAscent(ascent);
    m_fontMetrics.setDescent(descent);
    m_fontMetrics.setLineGap(lineGap);
    m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
    m_avgCharWidth = textMetrics.tmAveCharWidth;
    m_maxCharWidth = textMetrics.tmMaxCharWidth;
    float xHeight = ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
    GLYPHMETRICS gm;
    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
    DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &identity);
    if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
        xHeight = gm.gmptGlyphOrigin.y;
    m_fontMetrics.setXHeight(xHeight);
    m_fontMetrics.setUnitsPerEm(metrics.otmEMSquare);

    SelectObject(hdc, oldFont);
}
示例#19
0
void FenetreZoom::TracerZoom(wxRect &rSrc)
{
    if (zoomInactif)
        return;
    ImageInfoCV*	imAcq=fMere->ImAcq();
    if (rSrc.GetHeight()<=0 || rSrc.GetWidth()<=0 || imAcq->cols<=0)
        return;
    if (rSrc.GetHeight()+rSrc.y>=imAcq->rows || rSrc.GetWidth()+rSrc.x>=imAcq->cols)
        return;
    wxImage *d=fMere->ImageAffichee();
    wxClientDC hdc(this);

    hdc.SetBrush(*wxBLACK_BRUSH);

    wxRect		src=rSrc;
    wxRect		r=GetClientSize();

    int zoomX =r.GetWidth()/rSrc.GetWidth()+1;
    int zoomY =r.GetHeight()/rSrc.GetHeight()+1;

    if (zoomX<zoomY)
        zoomY=zoomX;
    else
        zoomX=zoomY;
    if (zoomX*zoomY==0)
        return;

    wxRect		dst(0,0,zoomX*rSrc.GetWidth(),zoomY*rSrc.GetHeight());
//SetClientSize(dst);

    hdc.DrawRectangle(r.GetRight(),r.GetTop(),r.GetRight(),r.GetBottom());
    wxImage		sousImage=d->GetSubImage(rSrc);
//	sousImage.SetMask(0);
    wxImage		imageZoom=sousImage.Scale(dst.GetRight()-dst.GetLeft()+1,dst.GetBottom()-dst.GetTop()+1);
//	imageZoom.SetMask(0);

    wxBitmap	b(imageZoom);
    hdc.DrawBitmap(b,0,0);
    hdc.SetPen(*wxBLACK);
    hdc.DrawRectangle(dst.GetRight(),r.GetTop(),r.GetRight(),r.GetBottom());
    hdc.DrawRectangle(r.GetLeft(),dst.GetBottom(),r.GetRight(),r.GetBottom());

}
示例#20
0
void FenetreZoom::TracerZoom(wxPoint p)
{
    if (zoomInactif)
    {
        if (!IsShown())

            return;
        zoomInactif =false;
    }
    ImageInfoCV*	imAcq=fMere->ImAcq();
    wxImage *d=fMere->ImageAffichee();
    wxClientDC hdc(this);

    hdc.SetBrush(*wxBLACK_BRUSH);
    if (facteurZoom!=0)
    {
        if (imAcq && imAcq->cols>0)
        {
            wxRect		src(0,0,imAcq->cols,imAcq->rows);
            wxRect		dst=CalculPosRectDst(src,&p),r=GetClientSize();
            hdc.DrawRectangle(r.GetRight(),r.GetTop(),r.GetRight(),r.GetBottom());
            wxRect		rSrc(src.GetLeft(),src.GetTop(),src.GetRight()-src.GetLeft()+1,src.GetBottom()-src.GetTop()+1);
            wxImage		sousImage=d->GetSubImage(rSrc);
            //	sousImage.SetMask(0);
            wxImage		imageZoom=sousImage.Scale(dst.GetRight()-dst.GetLeft()+1,dst.GetBottom()-dst.GetTop()+1);
            //	imageZoom.SetMask(0);

            wxBitmap	b(imageZoom);
            hdc.DrawBitmap(b,0,0);
            hdc.SetPen(*wxBLACK);
            hdc.DrawRectangle(dst.GetRight(),r.GetTop(),r.GetRight(),r.GetBottom());
            hdc.DrawRectangle(r.GetLeft(),dst.GetBottom(),r.GetRight(),r.GetBottom());
        }
    }
    else
    {
        wxBitmap pub(*d);
        hdc.DrawBitmap(pub,-p.x,-p.y);
    }
}
FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
{
    HWndDC hdc(0);
    SetGraphicsMode(hdc, GM_ADVANCED);
    HGDIOBJ oldFont = SelectObject(hdc, m_platformData.hfont());

    GLYPHMETRICS gdiMetrics;
    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
    if (GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gdiMetrics, 0, 0, &identity) == -1) {
        if (FontPlatformData::ensureFontLoaded(m_platformData.hfont())) {
            // Retry GetTextMetrics.
            // FIXME: Handle gracefully the error if this call also fails.
            // See http://crbug.com/6401.
            if (GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gdiMetrics, 0, 0, &identity) == -1)
                LOG_ERROR("Unable to get the glyph metrics after second attempt");
        }
    }

    SelectObject(hdc, oldFont);

    return FloatRect(gdiMetrics.gmptGlyphOrigin.x, -gdiMetrics.gmptGlyphOrigin.y,
        gdiMetrics.gmBlackBoxX, gdiMetrics.gmBlackBoxY);
}
示例#22
0
void CPlayerToolBar::OnPaint()
{
  //LONGLONG startTime = AfxGetMyApp()->GetPerfCounter();
  CPaintDC dc(this); // device context for painting
  CRect paintRect(dc.m_ps.rcPaint);
  AppSettings& s = AfxGetAppSettings();

  CRect rcClient;
  GetClientRect(&rcClient);
  CMemoryDC hdc(&dc, rcClient);
  hdc.SetBkMode(TRANSPARENT);

  CRect rc;
  GetWindowRect(&rc);

  if( paintRect == m_btnVolBG->m_rcHitest){
    m_btnVolBG->OnPaint( &hdc, rc);
    m_btnVolTm->OnPaint( &hdc, rc);

    return;
  }

  CRect rcBottomSqu = rcClient;
  rcBottomSqu.top = rcBottomSqu.bottom - 10;

  CRect rcUpperSqu = rcClient;

  CMainFrame* pFrame = ((CMainFrame*)AfxGetMainWnd());

  if (s.skinid == ID_SKIN_FIRST)
    hdc.FillSolidRect(rcUpperSqu, s.GetColorFromTheme(_T("ToolBarBG"), NEWUI_COLOR_TOOLBAR_UPPERBG));
  else
  {

    CBitmap* cbm = CBitmap::FromHandle(pFrame->m_btoolbarbg);
    CDC bmpDc;
    bmpDc.CreateCompatibleDC(&hdc);
    HBITMAP oldhbm = (HBITMAP)bmpDc.SelectObject(cbm);
    BITMAP btmp;
    cbm->GetBitmap(&btmp);
    hdc.StretchBlt(0, 0, rcUpperSqu.Width(), rcUpperSqu.Height(), &bmpDc, 0, 0, btmp.bmWidth, btmp.bmHeight - 2, SRCCOPY);
    bmpDc.SelectObject(oldhbm);
  }
  HFONT holdft = NULL;
  if (m_adctrl.GetVisible())
    holdft = (HFONT)hdc.SelectObject(m_adsft);
  else
    holdft = (HFONT)hdc.SelectObject(m_statft);
  hdc.SetTextColor(s.GetColorFromTheme(_T("ToolBarTimeText"), 0xffffff) );

  UpdateButtonStat();

  int volume = min( m_volctrl.GetPos() , m_volctrl.GetRangeMax() );
  m_btnVolTm->m_rcHitest.MoveToXY(m_btnVolBG->m_rcHitest.left +  ( m_btnVolBG->m_rcHitest.Width() * volume / m_volctrl.GetRangeMax() ) - m_btnVolTm->m_rcHitest.Width()/2
    , m_btnVolBG->m_rcHitest.top + (m_btnVolBG->m_rcHitest.Height() -  m_btnVolTm->m_rcHitest.Height() ) / 2 );
  
  m_btnList.PaintAll(&hdc, rc);

  std::wstring sTimeBtnString = m_adctrl.GetCurAd();

  if (!sTimeBtnString.empty())
  {
    int prom_margin = 8;
    CSize size = dc.GetTextExtent(sTimeBtnString.c_str());

    CSUIButton* cbtn = m_btnList.GetButton(L"SHARE");
    
    if (cbtn && cbtn->m_currenthide)
    {
      cbtn = m_btnList.GetButton(L"LOGO");
      if (cbtn && !cbtn->m_currenthide)
        prom_margin = -10;
    }
    if (cbtn && cbtn->m_currenthide)
      cbtn = NULL;
    
    CRect btnrc(prom_margin, 0, 0, 0);
    if (cbtn)
    {
      btnrc = cbtn->m_rcHitest - rc.TopLeft();
      btnrc.left = btnrc.right + prom_margin;
    }
    
    int width = m_btnList.GetRelativeMinLength(rc, cbtn) - prom_margin;
    if (cbtn)
      width -= cbtn->m_rcHitest.Width();

    if (width < 30)
      width = 0;
   
    if (size.cx > 0)
      btnrc.right = btnrc.left + width;//min(width, size.cx);
    else
      btnrc.right = btnrc.left;
    //btnrc.right -= 5;
    btnrc.top = (rc.Height() - size.cy) / 2;
    btnrc.bottom = btnrc.top + size.cy;
    
    m_adctrl.SetRect(btnrc, &hdc);
    m_adctrl.Paint(&hdc);  
  }
  hdc.SelectObject(holdft);

}
示例#23
0
static bool PrintToDevice(const PrintData &pd, ProgressUpdateUI *progressUI = nullptr,
                          AbortCookieManager *abortCookie = nullptr) {
    AssertCrash(pd.engine);
    if (!pd.engine)
        return false;
    AssertCrash(pd.printerName);
    if (!pd.printerName)
        return false;

    BaseEngine &engine = *pd.engine;
    ScopedMem<WCHAR> fileName;

    DOCINFO di = { 0 };
    di.cbSize = sizeof(DOCINFO);
    if (gPluginMode) {
        fileName.Set(url::GetFileName(gPluginURL));
        // fall back to a generic "filename" instead of the more confusing temporary filename
        di.lpszDocName = fileName ? fileName : L"filename";
    } else
        di.lpszDocName = engine.FileName();

    int current = 1, total = 0;
    if (pd.sel.Count() == 0) {
        for (size_t i = 0; i < pd.ranges.Count(); i++) {
            if (pd.ranges.At(i).nToPage < pd.ranges.At(i).nFromPage)
                total += pd.ranges.At(i).nFromPage - pd.ranges.At(i).nToPage + 1;
            else
                total += pd.ranges.At(i).nToPage - pd.ranges.At(i).nFromPage + 1;
        }
    } else {
        for (int pageNo = 1; pageNo <= engine.PageCount(); pageNo++) {
            if (!BoundSelectionOnPage(pd.sel, pageNo).IsEmpty())
                total++;
        }
    }
    AssertCrash(total > 0);
    if (0 == total)
        return false;
    if (progressUI)
        progressUI->UpdateProgress(current, total);

    // cf. http://blogs.msdn.com/b/oldnewthing/archive/2012/11/09/10367057.aspx
    ScopeHDC hdc(CreateDC(nullptr, pd.printerName, nullptr, pd.devMode));
    if (!hdc)
        return false;

    if (StartDoc(hdc, &di) <= 0)
        return false;

    // MM_TEXT: Each logical unit is mapped to one device pixel.
    // Positive x is to the right; positive y is down.
    SetMapMode(hdc, MM_TEXT);

    const SizeI paperSize(GetDeviceCaps(hdc, PHYSICALWIDTH), GetDeviceCaps(hdc, PHYSICALHEIGHT));
    const RectI printable(GetDeviceCaps(hdc, PHYSICALOFFSETX), GetDeviceCaps(hdc, PHYSICALOFFSETY),
                          GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES));
    const float dpiFactor = std::min(GetDeviceCaps(hdc, LOGPIXELSX) / engine.GetFileDPI(),
                                     GetDeviceCaps(hdc, LOGPIXELSY) / engine.GetFileDPI());
    bool bPrintPortrait = paperSize.dx < paperSize.dy;
    if (pd.devMode && (pd.devMode.Get()->dmFields & DM_ORIENTATION))
        bPrintPortrait = DMORIENT_PORTRAIT == pd.devMode.Get()->dmOrientation;

    if (pd.sel.Count() > 0) {
        for (int pageNo = 1; pageNo <= engine.PageCount(); pageNo++) {
            RectD bounds = BoundSelectionOnPage(pd.sel, pageNo);
            if (bounds.IsEmpty())
                continue;

            if (progressUI)
                progressUI->UpdateProgress(current, total);

            StartPage(hdc);

            geomutil::SizeT<float> bSize = bounds.Size().Convert<float>();
            float zoom = std::min((float)printable.dx / bSize.dx, (float)printable.dy / bSize.dy);
            // use the correct zoom values, if the page fits otherwise
            // and the user didn't ask for anything else (default setting)
            if (PrintScaleShrink == pd.advData.scale)
                zoom = std::min(dpiFactor, zoom);
            else if (PrintScaleNone == pd.advData.scale)
                zoom = dpiFactor;

            for (size_t i = 0; i < pd.sel.Count(); i++) {
                if (pd.sel.At(i).pageNo != pageNo)
                    continue;

                RectD *clipRegion = &pd.sel.At(i).rect;
                PointI offset((int)((clipRegion->x - bounds.x) * zoom),
                              (int)((clipRegion->y - bounds.y) * zoom));
                if (pd.advData.scale != PrintScaleNone) {
                    // center the selection on the physical paper
                    offset.x += (int)(printable.dx - bSize.dx * zoom) / 2;
                    offset.y += (int)(printable.dy - bSize.dy * zoom) / 2;
                }

                bool ok = false;
                short shrink = 1;
                do {
                    RenderedBitmap *bmp = engine.RenderBitmap(
                        pd.sel.At(i).pageNo, zoom / shrink, pd.rotation, clipRegion, Target_Print,
                        abortCookie ? &abortCookie->cookie : nullptr);
                    if (abortCookie)
                        abortCookie->Clear();
                    if (bmp && bmp->GetBitmap()) {
                        RectI rc(offset.x, offset.y, bmp->Size().dx * shrink,
                                 bmp->Size().dy * shrink);
                        ok = bmp->StretchDIBits(hdc, rc);
                    }
                    delete bmp;
                    shrink *= 2;
                } while (!ok && shrink < 32 && !(progressUI && progressUI->WasCanceled()));
            }
            // TODO: abort if !ok?

            if (EndPage(hdc) <= 0 || progressUI && progressUI->WasCanceled()) {
                AbortDoc(hdc);
                return false;
            }
            current++;
        }

        EndDoc(hdc);
        return false;
    }

    // print all the pages the user requested
    for (size_t i = 0; i < pd.ranges.Count(); i++) {
        int dir = pd.ranges.At(i).nFromPage > pd.ranges.At(i).nToPage ? -1 : 1;
        for (DWORD pageNo = pd.ranges.At(i).nFromPage; pageNo != pd.ranges.At(i).nToPage + dir;
             pageNo += dir) {
            if ((PrintRangeEven == pd.advData.range && pageNo % 2 != 0) ||
                (PrintRangeOdd == pd.advData.range && pageNo % 2 == 0))
                continue;
            if (progressUI)
                progressUI->UpdateProgress(current, total);

            StartPage(hdc);

            geomutil::SizeT<float> pSize = engine.PageMediabox(pageNo).Size().Convert<float>();
            int rotation = 0;
            // Turn the document by 90 deg if it isn't in portrait mode
            if (pSize.dx > pSize.dy) {
                rotation += 90;
                std::swap(pSize.dx, pSize.dy);
            }
            // make sure not to print upside-down
            rotation = (rotation % 180) == 0 ? 0 : 270;
            // finally turn the page by (another) 90 deg in landscape mode
            if (!bPrintPortrait) {
                rotation = (rotation + 90) % 360;
                std::swap(pSize.dx, pSize.dy);
            }

            // dpiFactor means no physical zoom
            float zoom = dpiFactor;
            // offset of the top-left corner of the page from the printable area
            // (negative values move the page into the left/top margins, etc.);
            // offset adjustments are needed because the GDI coordinate system
            // starts at the corner of the printable area and we rather want to
            // center the page on the physical paper (except for PrintScaleNone
            // where the page starts at the very top left of the physical paper so
            // that printing forms/labels of varying size remains reliably possible)
            PointI offset(printable.x, printable.y);

            if (pd.advData.scale != PrintScaleNone) {
                // make sure to fit all content into the printable area when scaling
                // and the whole document page on the physical paper
                RectD rect = engine.PageContentBox(pageNo, Target_Print);
                geomutil::RectT<float> cbox =
                    engine.Transform(rect, pageNo, 1.0, rotation).Convert<float>();
                zoom = std::min((float)printable.dx / cbox.dx,
                                std::min((float)printable.dy / cbox.dy,
                                         std::min((float)paperSize.dx / pSize.dx,
                                                  (float)paperSize.dy / pSize.dy)));
                // use the correct zoom values, if the page fits otherwise
                // and the user didn't ask for anything else (default setting)
                if (PrintScaleShrink == pd.advData.scale && dpiFactor < zoom)
                    zoom = dpiFactor;
                // center the page on the physical paper
                offset.x += (int)(paperSize.dx - pSize.dx * zoom) / 2;
                offset.y += (int)(paperSize.dy - pSize.dy * zoom) / 2;
                // make sure that no content lies in the non-printable paper margins
                geomutil::RectT<float> onPaper(printable.x + offset.x + cbox.x * zoom,
                                               printable.y + offset.y + cbox.y * zoom,
                                               cbox.dx * zoom, cbox.dy * zoom);
                if (onPaper.x < printable.x)
                    offset.x += (int)(printable.x - onPaper.x);
                else if (onPaper.BR().x > printable.BR().x)
                    offset.x -= (int)(onPaper.BR().x - printable.BR().x);
                if (onPaper.y < printable.y)
                    offset.y += (int)(printable.y - onPaper.y);
                else if (onPaper.BR().y > printable.BR().y)
                    offset.y -= (int)(onPaper.BR().y - printable.BR().y);
            }

            bool ok = false;
            short shrink = 1;
            do {
                RenderedBitmap *bmp =
                    engine.RenderBitmap(pageNo, zoom / shrink, rotation, nullptr, Target_Print,
                                        abortCookie ? &abortCookie->cookie : nullptr);
                if (abortCookie)
                    abortCookie->Clear();
                if (bmp && bmp->GetBitmap()) {
                    RectI rc(offset.x, offset.y, bmp->Size().dx * shrink, bmp->Size().dy * shrink);
                    ok = bmp->StretchDIBits(hdc, rc);
                }
                delete bmp;
                shrink *= 2;
            } while (!ok && shrink < 32 && !(progressUI && progressUI->WasCanceled()));
            // TODO: abort if !ok?

            if (EndPage(hdc) <= 0 || progressUI && progressUI->WasCanceled()) {
                AbortDoc(hdc);
                return false;
            }
            current++;
        }
    }

    EndDoc(hdc);
    return true;
}
示例#24
0
STDMETHODIMP CompositeOverlayImpl<B>::ModernRender(long _hdc)
{
	short count = 0;
	Count(&count);

	for (int i=count-1; i>=0; i--)
	{
		IOverlay *pItem;
		Item(CComVariant(i), &pItem);
		VARIANT_BOOL vis;
		pItem->get_Visible(&vis);
		if (vis)
		{
			ISimpleOverlay2 *pISO2 = NULL;
			HRESULT hr = pItem->QueryInterface(__uuidof(ISimpleOverlay2), (void **)&pISO2);
			if (SUCCEEDED(hr))
			{
				IOverlay *effectOverlay;
				pISO2->get_EffectOverlay(&effectOverlay);
				long effect;
				pISO2->get_EffectOverlayEffect(&effect);

				if (!effectOverlay)
				{
					pItem->Render(_hdc);
				}
				else
				{
					// prevent recursion
					pISO2->put_EffectOverlay(NULL);

					// Create a private HDC to draw into so that we can mask it.
					long width = 128;
					long height = 128;
					model->get_Width(&width);
					model->get_Height(&height);
					HDCImage hdc((HDC)_hdc, width, height);

					// Render the item
					pItem->Render(hdc);

					// Now mask it
					HDCImage hdcMask((HDC)hdc, width, height);
					effectOverlay->Render(hdcMask);
					switch(effect)
					{
					case 0:
						hdc.MaskOut(hdcMask);
						break;

					case 1:
						hdc.MaskIn(hdcMask);
						break;
					}

					// Copy private HDC into the passed HDC
					Graphics g((HDC)_hdc);
					g.DrawImage(
					   &hdc.GetImage(), 
					   Rect(0, 0, width, height),	// Destination rectangle
					   0,						// Source rectangle X 
					   0,						// Source rectangle Y
					   width,		// Source rectangle width
					   height,		// Source rectangle height
					   UnitPixel);

					// Reset recursion avoider
					pISO2->put_EffectOverlay(effectOverlay);
				}

				pISO2->Release();
			}
			else
				pItem->Render(_hdc);
		}
		pItem->Release();
	}

	return S_OK;
}
示例#25
0
STDMETHODIMP CompositeOverlayImpl<B>::Render(long _hdc)
{
	short count = 0;
	Count(&count);

	REAL el[6];
	CumulativeTransform(el);
	Matrix matrix(el[0], el[1], el[2], el[3], el[4], el[5]);

	// Firstly, if us or our parents don't transform the coordinate space, life is simple.
	if (matrix.IsIdentity())
	{
		ModernRender(_hdc);
	}
	else
	{
		// Check if all children are of type ISimpleOverlay2
		bool iso2 = true;
		for (int i=count-1; i>=0; i--)
		{
			IOverlay *pItem;
			Item(CComVariant(i), &pItem);
			VARIANT_BOOL vis;
			pItem->get_Visible(&vis);
			if (vis)
			{
				ISimpleOverlay2 *pISO2 = NULL;
				HRESULT hr = pItem->QueryInterface(__uuidof(ISimpleOverlay2), (void **)&pISO2);
				if (!SUCCEEDED(hr))
					iso2 = false;
				else
					pISO2->Release();
			}
			pItem->Release();
		}

		// If all children are of type ISimpleOverlay2, life is also simple.
		if (iso2)
		{
			ModernRender(_hdc);
		}
		else
		{
			// Otherwise, draw into a pre-transformed hdc.
			long width = 128;
			long height = 128;
			model->get_Width(&width);
			model->get_Height(&height);

			HDCImage hdc((HDC)_hdc, width, height);

			for (int i=count-1; i>=0; i--)
			{
				IOverlay *pItem;
				Item(CComVariant(i), &pItem);
				VARIANT_BOOL vis;
				pItem->get_Visible(&vis);
				if (vis)
					pItem->Render(hdc);
				pItem->Release();
			}

			Graphics g((HDC)_hdc);
			g.SetInterpolationMode(InterpolationModeHighQuality);
			g.SetSmoothingMode(SmoothingModeAntiAlias);
			g.MultiplyTransform(&matrix);
			g.DrawImage(&hdc.GetImage(), 0, 0);
		}
	}

	return S_OK;
}
示例#26
0
static bool PrintToDevice(PrintData& pd, ProgressUpdateUI *progressUI=NULL, AbortCookieManager *abortCookie=NULL)
{
    AssertCrash(pd.engine);
    if (!pd.engine)
        return false;
    AssertCrash(pd.printerName);
    if (!pd.printerName)
        return false;

    BaseEngine& engine = *pd.engine;
    ScopedMem<WCHAR> fileName;

    DOCINFO di = { 0 };
    di.cbSize = sizeof (DOCINFO);
    if (gPluginMode) {
        fileName.Set(ExtractFilenameFromURL(gPluginURL));
        // fall back to a generic "filename" instead of the more confusing temporary filename
        di.lpszDocName = fileName ? fileName : L"filename";
    }
    else
        di.lpszDocName = engine.FileName();

    int current = 1, total = 0;
    if (pd.sel.Count() == 0) {
        for (size_t i = 0; i < pd.ranges.Count(); i++) {
            if (pd.ranges.At(i).nToPage < pd.ranges.At(i).nFromPage)
                total += pd.ranges.At(i).nFromPage - pd.ranges.At(i).nToPage + 1;
            else
                total += pd.ranges.At(i).nToPage - pd.ranges.At(i).nFromPage + 1;
        }
    }
    else {
        for (int pageNo = 1; pageNo <= engine.PageCount(); pageNo++) {
            if (!BoundSelectionOnPage(pd.sel, pageNo).IsEmpty())
                total++;
        }
    }
    AssertCrash(total > 0);
    if (0 == total)
        return false;
    if (progressUI)
        progressUI->UpdateProgress(current, total);

    // cf. http://code.google.com/p/sumatrapdf/issues/detail?id=1882
    // According to our crash dumps, Cannon printer drivers (caprenn.dll etc.)
    // are buggy and like to crash during printing with DEP violation
    // We disable dep during printing to hopefully not crash
    // TODO: even better would be to print in a separate process so that
    // crashes during printing wouldn't affect the main process. It's also
    // much more complicated to implement
    ScopeDisableDEP scopeNoDEP;

    // cf. http://blogs.msdn.com/b/oldnewthing/archive/2012/11/09/10367057.aspx
    ScopeHDC hdc(CreateDC(pd.driverName, pd.printerName, pd.portName, pd.devMode));
    if (!hdc)
        return false;

    if (StartDoc(hdc, &di) <= 0)
        return false;

    // MM_TEXT: Each logical unit is mapped to one device pixel.
    // Positive x is to the right; positive y is down.
    SetMapMode(hdc, MM_TEXT);

    const SizeI paperSize(GetDeviceCaps(hdc, PHYSICALWIDTH),
                          GetDeviceCaps(hdc, PHYSICALHEIGHT));
    const RectI printable(GetDeviceCaps(hdc, PHYSICALOFFSETX),
                          GetDeviceCaps(hdc, PHYSICALOFFSETY),
                          GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES));
    const float dpiFactor = min(GetDeviceCaps(hdc, LOGPIXELSX) / engine.GetFileDPI(),
                                GetDeviceCaps(hdc, LOGPIXELSY) / engine.GetFileDPI());
    bool bPrintPortrait = paperSize.dx < paperSize.dy;
    if (pd.devMode && (pd.devMode.Get()->dmFields & DM_ORIENTATION))
        bPrintPortrait = DMORIENT_PORTRAIT == pd.devMode.Get()->dmOrientation;

    if (pd.sel.Count() > 0) {
        for (int pageNo = 1; pageNo <= engine.PageCount(); pageNo++) {
            RectD bounds = BoundSelectionOnPage(pd.sel, pageNo);
            if (bounds.IsEmpty())
                continue;

            if (progressUI)
                progressUI->UpdateProgress(current, total);

            StartPage(hdc);

            SizeT<float> bSize = bounds.Size().Convert<float>();
            float zoom = min((float)printable.dx / bSize.dx,
                             (float)printable.dy / bSize.dy);
            // use the correct zoom values, if the page fits otherwise
            // and the user didn't ask for anything else (default setting)
            if (PrintScaleShrink == pd.advData.scale)
                zoom = min(dpiFactor, zoom);
            else if (PrintScaleNone == pd.advData.scale)
                zoom = dpiFactor;

            for (size_t i = 0; i < pd.sel.Count(); i++) {
                if (pd.sel.At(i).pageNo != pageNo)
                    continue;

                RectD *clipRegion = &pd.sel.At(i).rect;
                PointI offset((int)((clipRegion->x - bounds.x) * zoom), (int)((clipRegion->y - bounds.y) * zoom));
                if (!pd.advData.asImage) {
                    RectI rc((int)(printable.dx - bSize.dx * zoom) / 2 + offset.x,
                             (int)(printable.dy - bSize.dy * zoom) / 2 + offset.y,
                             (int)(clipRegion->dx * zoom), (int)(clipRegion->dy * zoom));
                    engine.RenderPage(hdc, rc, pd.sel.At(i).pageNo, zoom, pd.rotation, clipRegion, Target_Print, abortCookie ? &abortCookie->cookie : NULL);
                    if (abortCookie)
                        abortCookie->Clear();
                }
                else {
                    RenderedBitmap *bmp = NULL;
                    short shrink = 1;
                    do {
                        bmp = engine.RenderBitmap(pd.sel.At(i).pageNo, zoom / shrink, pd.rotation, clipRegion, Target_Print, abortCookie ? &abortCookie->cookie : NULL);
                        if (abortCookie)
                            abortCookie->Clear();
                        if (!bmp || !bmp->GetBitmap()) {
                            shrink *= 2;
                            delete bmp;
                            bmp = NULL;
                        }
                    } while (!bmp && shrink < 32 && !(progressUI && progressUI->WasCanceled()));
                    if (bmp) {
                        RectI rc((int)(paperSize.dx - bSize.dx * zoom) / 2 + offset.x,
                                 (int)(paperSize.dy - bSize.dy * zoom) / 2 + offset.y,
                                 bmp->Size().dx * shrink, bmp->Size().dy * shrink);
                        bmp->StretchDIBits(hdc, rc);
                        delete bmp;
                    }
                }
            }

            if (EndPage(hdc) <= 0 || progressUI && progressUI->WasCanceled()) {
                AbortDoc(hdc);
                return false;
            }
            current++;
        }

        EndDoc(hdc);
        return false;
    }

    // print all the pages the user requested
    for (size_t i = 0; i < pd.ranges.Count(); i++) {
        int dir = pd.ranges.At(i).nFromPage > pd.ranges.At(i).nToPage ? -1 : 1;
        for (DWORD pageNo = pd.ranges.At(i).nFromPage; pageNo != pd.ranges.At(i).nToPage + dir; pageNo += dir) {
            if ((PrintRangeEven == pd.advData.range && pageNo % 2 != 0) ||
                (PrintRangeOdd == pd.advData.range && pageNo % 2 == 0))
                continue;
            if (progressUI)
                progressUI->UpdateProgress(current, total);

            StartPage(hdc);

            SizeT<float> pSize = engine.PageMediabox(pageNo).Size().Convert<float>();
            int rotation = 0;
            // Turn the document by 90 deg if it isn't in portrait mode
            if (pSize.dx > pSize.dy) {
                rotation += 90;
                swap(pSize.dx, pSize.dy);
            }
            // make sure not to print upside-down
            rotation = (rotation % 180) == 0 ? 0 : 270;
            // finally turn the page by (another) 90 deg in landscape mode
            if (!bPrintPortrait) {
                rotation = (rotation + 90) % 360;
                swap(pSize.dx, pSize.dy);
            }

            // dpiFactor means no physical zoom
            float zoom = dpiFactor;
            // offset of the top-left corner of the page from the printable area
            // (negative values move the page into the left/top margins, etc.);
            // offset adjustments are needed because the GDI coordinate system
            // starts at the corner of the printable area and we rather want to
            // center the page on the physical paper (default behavior)
            PointI offset(-printable.x, -printable.y);

            if (pd.advData.scale != PrintScaleNone) {
                // make sure to fit all content into the printable area when scaling
                // and the whole document page on the physical paper
                RectD rect = engine.PageContentBox(pageNo, Target_Print);
                RectT<float> cbox = engine.Transform(rect, pageNo, 1.0, rotation).Convert<float>();
                zoom = min((float)printable.dx / cbox.dx,
                       min((float)printable.dy / cbox.dy,
                       min((float)paperSize.dx / pSize.dx,
                           (float)paperSize.dy / pSize.dy)));
                // use the correct zoom values, if the page fits otherwise
                // and the user didn't ask for anything else (default setting)
                if (PrintScaleShrink == pd.advData.scale && dpiFactor < zoom)
                    zoom = dpiFactor;
                // make sure that no content lies in the non-printable paper margins
                RectT<float> onPaper((paperSize.dx - pSize.dx * zoom) / 2 + cbox.x * zoom,
                                     (paperSize.dy - pSize.dy * zoom) / 2 + cbox.y * zoom,
                                     cbox.dx * zoom, cbox.dy * zoom);
                if (onPaper.x < printable.x)
                    offset.x += (int)(printable.x - onPaper.x);
                else if (onPaper.BR().x > printable.BR().x)
                    offset.x -= (int)(onPaper.BR().x - printable.BR().x);
                if (onPaper.y < printable.y)
                    offset.y += (int)(printable.y - onPaper.y);
                else if (onPaper.BR().y > printable.BR().y)
                    offset.y -= (int)(onPaper.BR().y - printable.BR().y);
            }

            if (!pd.advData.asImage) {
                RectI rc = RectI::FromXY((int)(paperSize.dx - pSize.dx * zoom) / 2 + offset.x,
                                         (int)(paperSize.dy - pSize.dy * zoom) / 2 + offset.y,
                                         paperSize.dx, paperSize.dy);
                engine.RenderPage(hdc, rc, pageNo, zoom, rotation, NULL, Target_Print, abortCookie ? &abortCookie->cookie : NULL);
                if (abortCookie)
                    abortCookie->Clear();
            }
            else {
                RenderedBitmap *bmp = NULL;
                short shrink = 1;
                do {
                    bmp = engine.RenderBitmap(pageNo, zoom / shrink, rotation, NULL, Target_Print, abortCookie ? &abortCookie->cookie : NULL);
                    if (abortCookie)
                        abortCookie->Clear();
                    if (!bmp || !bmp->GetBitmap()) {
                        shrink *= 2;
                        delete bmp;
                        bmp = NULL;
                    }
                } while (!bmp && shrink < 32 && !(progressUI && progressUI->WasCanceled()));
                if (bmp) {
                    RectI rc((paperSize.dx - bmp->Size().dx * shrink) / 2 + offset.x,
                             (paperSize.dy - bmp->Size().dy * shrink) / 2 + offset.y,
                             bmp->Size().dx * shrink, bmp->Size().dy * shrink);
                    bmp->StretchDIBits(hdc, rc);
                    delete bmp;
                }
            }

            if (EndPage(hdc) <= 0 || progressUI && progressUI->WasCanceled()) {
                AbortDoc(hdc);
                return false;
            }
            current++;
        }
    }

    EndDoc(hdc);
    return true;
}
示例#27
0
// Draws the Mandelbrot set
void DrawSetParallel(HWND hWnd)
{
    HDC hdc(GetDC(hWnd));                  // Get device context

    // Get client area dimensions, which will be the image size
    RECT rect;
    GetClientRect(hWnd, &rect);
    int imageHeight(rect.bottom);
    int imageWidth(rect.right);

    // Create bitmap for one row of pixels in image
    HDC memDC1 = CreateCompatibleDC(hdc);   // Get device context to draw pixels
    HDC memDC2 = CreateCompatibleDC(hdc);   // Get device context to draw pixels
    HBITMAP bmp1 = CreateCompatibleBitmap(hdc, imageWidth, 1);
    HBITMAP bmp2 = CreateCompatibleBitmap(hdc, imageWidth, 1);
    HGDIOBJ oldBmp1 = SelectObject(memDC1, bmp1);   // Select bitmap into DC1
    HGDIOBJ oldBmp2 = SelectObject(memDC2, bmp2);   // Select bitmap into DC2

    // Client area axes
    const double realMin(-2.1);       // Minimum real value
    double imaginaryMin(-1.3);        // Minimum imaginary value
    double imaginaryMax(+1.3);        // Maximum imaginary value

    // Set maximum imaginary so axes are the same scale
    double realMax(realMin + (imaginaryMax - imaginaryMin)*imageWidth / imageHeight);

    // Get scale factors to convert pixel coordinates
    double realScale((realMax - realMin) / (imageWidth - 1));
    double imaginaryScale((imaginaryMax - imaginaryMin) / (imageHeight - 1));


    // Lambda expression to create an image row
    std::function<void(HDC&, int)> rowCalc = [&](HDC & memDC, int yLocal) {
        double zReal(0.0), cReal(0.0);
        double zImaginary(imaginaryMax - yLocal * imaginaryScale);
        double cImaginary(zImaginary);
        for (int x = 0 ; x < imageWidth ; ++x) {         // Iterate over pixels in a row
            zReal = cReal = realMin + x * realScale;
            // Set current pixel color based on n
            SetPixel(memDC, x, 0, Color(IteratePoint(zReal, zImaginary, cReal, cImaginary)));
        }
    };

    for (int y = 1 ; y < imageHeight ; y += 2) {          // Iterate over image rows
        Concurrency::parallel_invoke([&] {rowCalc(memDC1, y - 1);}, [&] {rowCalc(memDC2, y);});
        // Transfer pixel row to client area device context
        BitBlt(hdc, 0, y - 1, imageWidth, 1, memDC1, 0, 0, SRCCOPY);
        BitBlt(hdc, 0, y, imageWidth, 1, memDC2, 0, 0, SRCCOPY);
    }
    // If there's an odd number of rows, take care of the last one
    if (imageHeight % 2 == 1) {
        rowCalc(memDC1, imageWidth - 1);
        BitBlt(hdc, 0, imageHeight - 1, imageWidth, 1, memDC1, 0, 0, SRCCOPY);
    }

    SelectObject(memDC1, oldBmp1);
    SelectObject(memDC2, oldBmp2);
    DeleteObject(bmp1);                       // Delete bitmap 1
    DeleteObject(bmp2);                       // Delete bitmap 2
    DeleteDC(memDC1);                         // and our working DC 1
    DeleteDC(memDC2);                         // and our working DC 2
    ReleaseDC(hWnd, hdc);                     // and client area DC
}
示例#28
0
bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const Font* fontData, GlyphBuffer* glyphBuffer)
{
    // Determine the string for this item.
    const UChar* str = cp + m_items[i].iCharPos;
    int len = m_items[i+1].iCharPos - m_items[i].iCharPos;
    SCRIPT_ITEM item = m_items[i];

    // Set up buffers to hold the results of shaping the item.
    Vector<WORD> glyphs;
    Vector<WORD> clusters;
    Vector<SCRIPT_VISATTR> visualAttributes;
    clusters.resize(len);
     
    // Shape the item.
    // The recommended size for the glyph buffer is 1.5 * the character length + 16 in the uniscribe docs.
    // Apparently this is a good size to avoid having to make repeated calls to ScriptShape.
    glyphs.resize(1.5 * len + 16);
    visualAttributes.resize(glyphs.size());

    if (!shape(str, len, item, fontData, glyphs, clusters, visualAttributes))
        return true;

    // We now have a collection of glyphs.
    Vector<GOFFSET> offsets;
    Vector<int> advances;
    offsets.resize(glyphs.size());
    advances.resize(glyphs.size());
    int glyphCount = 0;
    HRESULT placeResult = ScriptPlace(0, fontData->scriptCache(), glyphs.data(), glyphs.size(), visualAttributes.data(),
                                      &item.a, advances.data(), offsets.data(), 0);
    if (placeResult == E_PENDING) {
        // The script cache isn't primed with enough info yet.  We need to select our HFONT into
        // a DC and pass the DC in to ScriptPlace.
        HWndDC hdc(0);
        HFONT hfont = fontData->platformData().hfont();
        HFONT oldFont = (HFONT)SelectObject(hdc, hfont);
        placeResult = ScriptPlace(hdc, fontData->scriptCache(), glyphs.data(), glyphs.size(), visualAttributes.data(),
                                  &item.a, advances.data(), offsets.data(), 0);
        SelectObject(hdc, oldFont);
    }
    
    if (FAILED(placeResult) || glyphs.isEmpty())
        return true;

    // Convert all chars that should be treated as spaces to use the space glyph.
    // We also create a map that allows us to quickly go from space glyphs back to their corresponding characters.
    Vector<int> spaceCharacters(glyphs.size());
    spaceCharacters.fill(-1);

    const float cLogicalScale = fontData->platformData().useGDI() ? 1.0f : 32.0f;
    float spaceWidth = fontData->spaceWidth() - fontData->syntheticBoldOffset();
    unsigned logicalSpaceWidth = spaceWidth * cLogicalScale;

    for (int k = 0; k < len; k++) {
        UChar ch = *(str + k);
        bool treatAsSpace = FontCascade::treatAsSpace(ch);
        bool treatAsZeroWidthSpace = FontCascade::treatAsZeroWidthSpace(ch);
        if (treatAsSpace || treatAsZeroWidthSpace) {
            // Substitute in the space glyph at the appropriate place in the glyphs
            // array.
            glyphs[clusters[k]] = fontData->spaceGlyph();
            advances[clusters[k]] = treatAsSpace ? logicalSpaceWidth : 0;
            if (treatAsSpace)
                spaceCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos;
        }
    }

    // Populate our glyph buffer with this information.
    bool hasExtraSpacing = m_font.letterSpacing() || m_font.wordSpacing() || m_padding;
    
    float leftEdge = m_runWidthSoFar;

    for (unsigned k = 0; k < glyphs.size(); k++) {
        Glyph glyph = glyphs[k];
        float advance = advances[k] / cLogicalScale;
        float offsetX = offsets[k].du / cLogicalScale;
        float offsetY = offsets[k].dv / cLogicalScale;

        // Match AppKit's rules for the integer vs. non-integer rendering modes.
        float roundedAdvance = roundf(advance);
        if (!fontData->platformData().isSystemFont()) {
            advance = roundedAdvance;
            offsetX = roundf(offsetX);
            offsetY = roundf(offsetY);
        }

        advance += fontData->syntheticBoldOffset();

        if (hasExtraSpacing) {
            // If we're a glyph with an advance, go ahead and add in letter-spacing.
            // That way we weed out zero width lurkers.  This behavior matches the fast text code path.
            if (advance && m_font.letterSpacing())
                advance += m_font.letterSpacing();

            // Handle justification and word-spacing.
            int characterIndex = spaceCharacters[k];
            // characterIndex is left at the initial value of -1 for glyphs that do not map back to treated-as-space characters.
            if (characterIndex != -1) {
                // Account for padding. WebCore uses space padding to justify text.
                // We distribute the specified padding over the available spaces in the run.
                if (m_padding) {
                    // Use leftover padding if not evenly divisible by number of spaces.
                    if (m_padding < m_padPerSpace) {
                        advance += m_padding;
                        m_padding = 0;
                    } else {
                        m_padding -= m_padPerSpace;
                        advance += m_padPerSpace;
                    }
                }

                // Account for word-spacing.
                if (characterIndex > 0 && m_font.wordSpacing()) {
                    UChar candidateSpace;
                    if (m_run.is8Bit())
                        candidateSpace = *(m_run.data8(characterIndex - 1));
                    else
                        candidateSpace = *(m_run.data16(characterIndex - 1));

                    if (!FontCascade::treatAsSpace(candidateSpace))
                        advance += m_font.wordSpacing();
                }
            }
        }

        m_runWidthSoFar += advance;

        // FIXME: We need to take the GOFFSETS for combining glyphs and store them in the glyph buffer
        // as well, so that when the time comes to draw those glyphs, we can apply the appropriate
        // translation.
        if (glyphBuffer) {
            FloatSize size(offsetX, -offsetY);
            glyphBuffer->add(glyph, fontData, advance, GlyphBuffer::noOffset, &size);
        }

        FloatRect glyphBounds = fontData->boundsForGlyph(glyph);
        glyphBounds.move(m_glyphOrigin.x(), m_glyphOrigin.y());
        m_minGlyphBoundingBoxX = min(m_minGlyphBoundingBoxX, glyphBounds.x());
        m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphBounds.maxX());
        m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, glyphBounds.y());
        m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphBounds.maxY());
        m_glyphOrigin.move(advance + offsetX, -offsetY);

        // Mutate the glyph array to contain our altered advances.
        if (m_computingOffsetPosition)
            advances[k] = advance;
    }

    while (m_computingOffsetPosition && m_offsetX >= leftEdge && m_offsetX < m_runWidthSoFar) {
        // The position is somewhere inside this run.
        int trailing = 0;
        HRESULT rc = ::ScriptXtoCP(m_offsetX - leftEdge, clusters.size(), glyphs.size(), clusters.data(), visualAttributes.data(),
                    advances.data(), &item.a, &m_offsetPosition, &trailing);
        if (FAILED(rc)) {
            WTFLogAlways("UniscribeController::shapeAndPlaceItem: ScriptXtoCP failed rc=%lx", rc);
            return true;
        }
        if (trailing && m_includePartialGlyphs && m_offsetPosition < len - 1) {
            m_offsetPosition += m_currentCharacter + m_items[i].iCharPos;
            m_offsetX += m_run.rtl() ? -trailing : trailing;
        } else {
            m_computingOffsetPosition = false;
            m_offsetPosition += m_currentCharacter + m_items[i].iCharPos;
            if (trailing && m_includePartialGlyphs)
               m_offsetPosition++;
            return false;
        }
    }

    return true;
}