コード例 #1
0
ファイル: EbookController.cpp プロジェクト: Jshauk/sumatrapdf
void EbookController::HandleMobiLayoutDone(EbookFormattingTask *ld)
{
    if (formattingThreadNo != ld->threadNo) {
        // this is a message from cancelled thread, we can disregard
        //lf("EbookController::MobiLayout() thread msg discarded, curr thread: %d, sending thread: %d", layoutThreadNo, ld->threadNo);
        return;
    }
    //lf("EbookController::HandleMobiLayoutMsg() %d pages, ld=0x%x", ld->pageCount, (int)ld);
    HtmlPage *pageToShow = NULL;

    if (!ld->fromBeginning) {
        // if this is the first page sent, we're currently showing a page
        // formatted for old window size. Replace that page with new page
        if (0 == formattingTemp.pagesFromPage.Count()) {
            CrashIf(0 == ld->pageCount);
            pageToShow = ld->pages[0];
        }
        formattingTemp.pagesFromPage.Append(ld->pages, ld->pageCount);
        if (pageToShow) {
            CrashIf(pageToShow->reparseIdx != pageShown->reparseIdx);
            ShowPage(pageToShow, false);
        }
        //lf("Got %d pages from page, total %d", ld->pageCount, formattingTemp.pagesFromPage.Count());
        //UpdateStatus();
        return;
    }

    // we're showing pages from the beginning
    if (-1 != startReparseIdx) {
        // we're formatting a book for which we need to restore
        // page from previous session
        CrashIf(formattingTemp.reparseIdx != 0);
        for (size_t i = 0; i < ld->pageCount; i++) {
            HtmlPage *pd = ld->pages[i];
            if (pd->reparseIdx == startReparseIdx) {
                pageToShow = pd;
            } else if (pd->reparseIdx >= startReparseIdx) {
                // this is the first page whose reparseIdx is greater than
                // the one we're looking for, so previous page has the data
                if (i > 0) {
                    pageToShow = ld->pages[i];
                    //lf("showing page %d", i);
                } else {
                    if (0 == formattingTemp.pagesFromBeginning.Count()) {
                        pageToShow = ld->pages[0];
                    } else {
                        size_t pageNo = formattingTemp.pagesFromBeginning.Count() - 1;
                        //lf("showing page %d from formattingTemp.pagesFromBeginning", (int)pageNo);
                        pageToShow = formattingTemp.pagesFromBeginning.At(pageNo);
                    }
                }
            }
            if (pageToShow) {
                startReparseIdx = -1;
                break;
            }
        }
    } else {
        if (0 == formattingTemp.pagesFromBeginning.Count()) {
            CrashIf(0 == ld->pageCount);
            pageToShow = ld->pages[0];
            //lf("showing ld->pages[0], pageCount = %d", ld->pageCount);
        }
    }

    formattingTemp.pagesFromBeginning.Append(ld->pages, ld->pageCount);
    //lf("Got %d pages from beginning, total %d", ld->pageCount, formattingTemp.pagesFromBeginning.Count());

    if (0 == formattingTemp.reparseIdx) {
        // if we're starting from the beginning, show the first page as
        // quickly as we can
        if (pageToShow)
            ShowPage(pageToShow, false);
    }

    if (ld->finished) {
        CrashIf(pagesFromBeginning || pagesFromPage);
        pagesFromBeginning = new Vec<HtmlPage *>(formattingTemp.pagesFromBeginning);
        formattingTemp.pagesFromBeginning.Reset();

        size_t pageCount = formattingTemp.pagesFromPage.Count();
        if (pageCount > 0) {
            pagesFromPage = new Vec<HtmlPage *>(formattingTemp.pagesFromPage);
            formattingTemp.pagesFromPage.Reset();
        }
        StopFormattingThread();
    }
    UpdateStatus();
}
コード例 #2
0
RectF TextRenderGdiplus::Measure(const WCHAR *s, size_t sLen) {
    CrashIf(!currFont);
    return MeasureText(gfx, currFont->font, s, sLen, measureAlgo);
}
コード例 #3
0
Gdiplus::RectF TextRenderHdc::Measure(const char *s, size_t sLen) {
    CrashIf(!currFont);
    CrashIf(!hdc);
    size_t strLen = str::Utf8ToWcharBuf(s, sLen, txtConvBuf, dimof(txtConvBuf));
    return Measure(txtConvBuf, strLen);
}
コード例 #4
0
 EbookFormattingData(HtmlPage **pages, size_t pageCount, bool finished, LONG threadNo) :
     pageCount(pageCount), finished(finished), threadNo(threadNo) {
     CrashIf(pageCount > MAX_PAGES);
     memcpy(this->pages, pages, pageCount * sizeof(*pages));
 }
コード例 #5
0
void TextRenderGdi::Unlock() {
    CrashIf(!hdcGfxLocked);
    gfx->ReleaseHDC(hdcGfxLocked);
    hdcGfxLocked = nullptr;
}
コード例 #6
0
ファイル: MuiHwndWrapper.cpp プロジェクト: Jshauk/sumatrapdf
void HwndWrapper::OnPaint(HWND hwnd)
{
    CrashIf(hwnd != hwndParent);
    painter->Paint(hwnd, repaintRequested);
    repaintRequested = false;
}
コード例 #7
0
ファイル: MuiFromText.cpp プロジェクト: Nargesf/Sumatrapdf
static void AddStyleProp(Style *style, TxtNode *prop)
{
    ScopedMem<char> tmp(prop->ValDup());

    if (prop->IsTextWithKey("name")) {
        style->SetName(tmp);
        return;
    }

    if (prop->IsTextWithKey("bg_col")) {
        style->Set(Prop::AllocColorSolid(PropBgColor, tmp));
        return;
    }

    if (prop->IsTextWithKey("col")) {
        style->Set(Prop::AllocColorSolid(PropColor, tmp));
        return;
    }

    if (prop->IsTextWithKey("parent")) {
        Style *parentStyle = StyleByName(tmp);
        CrashIf(!parentStyle);
        style->SetInheritsFrom(parentStyle);
        return;
    }

    if (prop->IsTextWithKey("border_width")) {
        style->SetBorderWidth(ParseFloat(tmp));
        return;
    }

    if (prop->IsTextWithKey("padding")) {
        ParsedPadding padding = { 0 };
        ParsePadding(tmp, padding);
        style->SetPadding(padding.top, padding.right, padding.bottom, padding.left);
        return;
    }

    if (prop->IsTextWithKey("stroke_width")) {
        style->Set(Prop::AllocWidth(PropStrokeWidth, ParseFloat(tmp)));
        return;
    }

    if (prop->IsTextWithKey("fill")) {
        style->Set(Prop::AllocColorSolid(PropFill, tmp));
        return;
    }

    if (prop->IsTextWithKey("vert_align")) {
        style->Set(Prop::AllocAlign(PropVertAlign, ParseElAlign(tmp)));
        return;
    }

    if (prop->IsTextWithKey("text_align")) {
        style->Set(Prop::AllocTextAlign(ParseAlignAttr(tmp)));
        return;
    }

    if (prop->IsTextWithKey("font_size")) {
        style->Set(Prop::AllocFontSize(ParseFloat(tmp)));
        return;
    }

    if (prop->IsTextWithKey("font_weight")) {
        style->Set(Prop::AllocFontWeight(ParseFontWeight(tmp)));
        return;
    }

    CrashIf(true);
}
コード例 #8
0
ファイル: GdiPlusUtil.cpp プロジェクト: sambhare/sumatrapdf
// 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;
}
コード例 #9
0
static void GetProps(Doc doc, PropertiesLayout *layoutData, DisplayModel *dm, bool extended)
{
    CrashIf(!doc.IsEngine() && !doc.IsEbook());
    DocType docType = doc.GetDocType();
    EngineType engineType = (docType >= Doc_BaseEngine) ? (EngineType)(docType - Doc_BaseEngine) : Engine_None;

    WCHAR *str = str::Dup(gPluginMode ? gPluginURL : doc.GetFilePath());
    layoutData->AddProperty(_TR("File:"), str);

    str = doc.GetProperty(Prop_Title);
    layoutData->AddProperty(_TR("Title:"), str);

    str = doc.GetProperty(Prop_Subject);
    layoutData->AddProperty(_TR("Subject:"), str);

    str = doc.GetProperty(Prop_Author);
    layoutData->AddProperty(_TR("Author:"), str);

    str = doc.GetProperty(Prop_Copyright);
    layoutData->AddProperty(_TR("Copyright:"), str);

    str = doc.GetProperty(Prop_CreationDate);
    if (Engine_PDF == engineType)
        ConvDateToDisplay(&str, PdfDateParse);
    else
        ConvDateToDisplay(&str, IsoDateParse);
    layoutData->AddProperty(_TR("Created:"), str);

    str = doc.GetProperty(Prop_ModificationDate);
    if (Engine_PDF == engineType)
        ConvDateToDisplay(&str, PdfDateParse);
    else
        ConvDateToDisplay(&str, IsoDateParse);
    layoutData->AddProperty(_TR("Modified:"), str);

    str = doc.GetProperty(Prop_CreatorApp);
    layoutData->AddProperty(_TR("Application:"), str);

    str = doc.GetProperty(Prop_PdfProducer);
    layoutData->AddProperty(_TR("PDF Producer:"), str);

    str = doc.GetProperty(Prop_PdfVersion);
    layoutData->AddProperty(_TR("PDF Version:"), str);

    str = FormatPdfFileStructure(doc);
    layoutData->AddProperty(_TR("PDF Optimizations:"), str);

    int64 fileSize = file::GetSize(doc.GetFilePath());
    if (-1 == fileSize && doc.IsEngine()) {
        size_t fileSizeT;
        if (ScopedMem<unsigned char>(doc.AsEngine()->GetFileData(&fileSizeT)))
            fileSize = fileSizeT;
    }
    if (-1 != fileSize) {
        str = FormatFileSize((size_t)fileSize);
        layoutData->AddProperty(_TR("File Size:"), str);
    }

    if (doc.IsEngine()) {
        str = str::Format(L"%d", doc.AsEngine()->PageCount());
        layoutData->AddProperty(_TR("Number of Pages:"), str);
    }

    if (dm && dm->engineType != Engine_Chm) {
        str = FormatPageSize(dm->engine, dm->CurrentPageNo(), dm->Rotation());
        if (IsUIRightToLeft() && IsVistaOrGreater()) {
            // ensure that the size remains ungarbled left-to-right
            // (note: XP doesn't know about \u202A...\u202C)
            str = str::Format(L"\u202A%s\u202C", ScopedMem<WCHAR>(str));
        }
        layoutData->AddProperty(_TR("Page Size:"), str);
    }

    str = FormatPermissions(doc);
    layoutData->AddProperty(_TR("Denied Permissions:"), str);

#if defined(DEBUG) || defined(ENABLE_EXTENDED_PROPERTIES)
    if (extended) {
        // TODO: FontList extraction can take a while
        str = doc.GetProperty(Prop_FontList);
        if (str) {
            // add a space between basic and extended file properties
            layoutData->AddProperty(L" ", str::Dup(L" "));
        }
        layoutData->AddProperty(_TR("Fonts:"), str);
    }
#endif
}
コード例 #10
0
// Requests the window to draw itself on a Graphics canvas.
// offX and offY is a position of this window within
// Graphics canvas (pos is relative to that offset)
void Control::Paint(Graphics *gfx, int offX, int offY)
{
    CrashIf(!IsVisible());
}
コード例 #11
0
ファイル: SvgPath.cpp プロジェクト: seancassell/sumatrapdf
static bool ParseSvgPathData(const char* s, VecSegmented<SvgPathInstr>& instr) {
    s = skipWs(s);

    while (*s) {
        SvgPathInstr i(GetInstructionType(*s++));
        switch (i.type) {
            case PathInstr::Close:
            case PathInstr::Close2:
                break;

            case PathInstr::HLineAbs:
            case PathInstr::HLineRel:
            case PathInstr::VLineAbs:
            case PathInstr::VLineRel:
                s = str::Parse(s, "%f", &i.v[0]);
                break;

            case PathInstr::MoveAbs:
            case PathInstr::MoveRel:
            case PathInstr::LineToAbs:
            case PathInstr::LineToRel:
            case PathInstr::BezierTAbs:
            case PathInstr::BezierTRel:
                s = str::Parse(s, "%f%_%?,%_%f", &i.v[0], &i.v[1]);
                break;

            case PathInstr::BezierSAbs:
            case PathInstr::BezierSRel:
            case PathInstr::BezierQAbs:
            case PathInstr::BezierQRel:
                s = str::Parse(s, "%f%_%?,%_%f,%f%_%?,%_%f", &i.v[0], &i.v[1], &i.v[2], &i.v[3]);
                break;

            case PathInstr::BezierCAbs:
            case PathInstr::BezierCRel:
                s = str::Parse(s, "%f%_%?,%_%f,%f%_%?,%_%f,%f%_%?,%_%f", &i.v[0], &i.v[1], &i.v[2], &i.v[3], &i.v[4],
                               &i.v[5]);
                break;

            case PathInstr::ArcAbs:
            case PathInstr::ArcRel: {
                int largeArc, sweep;
                s = str::Parse(s, "%f%_%?,%_%f%_%?,%_%f%_%?,%_%d%_%?,%_%d%_%?,%_%f%_%?,%_%f", &i.v[0], &i.v[1], &i.v[2],
                               &largeArc, &sweep, &i.v[3], &i.v[4]);
                i.largeArc = (largeArc != 0);
                i.sweep = (sweep != 0);
            } break;

            default:
                CrashIf(true);
                return false;
        }

        if (!s) {
            return false;
        }
        instr.Append(i);

        s = skipWs(s);
    }

    return true;
}
コード例 #12
0
ファイル: HtmlPullParser.cpp プロジェクト: Nargesf/Sumatrapdf
// Returns next part of html or NULL if finished
HtmlToken *HtmlPullParser::Next()
{
    if (currPos >= end)
        return NULL;

Next:
    const char *start = currPos;
    if (*currPos != '<' || currPos + 1 < end && !IsValidTagStart(*++currPos)) {
        // this must be text between tags
        if (!SkipUntil(currPos, end, '<') && IsSpaceOnly(start, currPos)) {
            // ignore whitespace after the last tag
            return NULL;
        }
        currToken.SetText(start, currPos);
        return &currToken;
    }

    // '<' - tag begins
    ++start;

    // skip <? and <! (processing instructions and comments)
    if (start < end && (('?' == *start) || ('!' == *start))) {
        if ('!' == *start && start + 2 < end && str::StartsWith(start, "!--")) {
            currPos = start + 3;
            if (!SkipUntil(currPos, end, "-->")) {
                currToken.SetError(HtmlToken::UnclosedTag, start);
                return &currToken;
            }
            currPos += 2;
        }
        else if (!SkipUntil(currPos, end, '>')) {
            currToken.SetError(HtmlToken::UnclosedTag, start);
            return &currToken;
        }
        ++currPos;
        goto Next;
    }

    if (!SkipUntilTagEnd(currPos, end)) {
        currToken.SetError(HtmlToken::UnclosedTag, start);
        return &currToken;
    }

    CrashIf('>' != *currPos);
    if (currPos == start || currPos == start + 1 && *start == '/') {
        // skip empty tags (</>), because we're lenient
        ++currPos;
        goto Next;
    }

    if (('/' == *start) && ('/' == currPos[-1])) { // </foo/>
        currToken.SetError(HtmlToken::InvalidTag, start);
    } else if ('/' == *start) { // </foo>
        currToken.SetTag(HtmlToken::EndTag, start + 1, currPos);
    } else if ('/' == currPos[-1]) { // <foo/>
        currToken.SetTag(HtmlToken::EmptyElementTag, start, currPos - 1);
    } else {
        currToken.SetTag(HtmlToken::StartTag, start, currPos);
    }
    ++currPos;
    return &currToken;
}
コード例 #13
0
// TODO: conceptually, RenderCache is not the right place for code that paints
//       (this is the only place that knows about Tiles, though)
UINT RenderCache::PaintTile(HDC hdc, RectI bounds, DisplayModel *dm, int pageNo,
                            TilePosition tile, RectI tileOnScreen, bool renderMissing,
                            bool *renderOutOfDateCue, bool *renderedReplacement)
{
    BitmapCacheEntry *entry = Find(dm, pageNo, dm->Rotation(), dm->ZoomReal(), &tile);
    UINT renderDelay = 0;

    if (!entry) {
        if (!isRemoteSession) {
            if (renderedReplacement)
                *renderedReplacement = true;
            entry = Find(dm, pageNo, dm->Rotation(), INVALID_ZOOM, &tile);
        }
        renderDelay = GetRenderDelay(dm, pageNo, tile);
        if (renderMissing && RENDER_DELAY_UNDEFINED == renderDelay && !IsRenderQueueFull())
            RequestRendering(dm, pageNo, tile);
    }
    RenderedBitmap *renderedBmp = entry ? entry->bitmap : NULL;
    HBITMAP hbmp = renderedBmp ? renderedBmp->GetBitmap() : NULL;

    if (!hbmp) {
        if (entry && !(renderedBmp && ReduceTileSize()))
            renderDelay = RENDER_DELAY_FAILED;
        else if (0 == renderDelay)
            renderDelay = 1;
        if (entry)
            DropCacheEntry(entry);
        return renderDelay;
    }

    HDC bmpDC = CreateCompatibleDC(hdc);
    if (bmpDC) {
        SizeI bmpSize = renderedBmp->Size();
        int xSrc = -min(tileOnScreen.x, 0);
        int ySrc = -min(tileOnScreen.y, 0);
        float factor = min(1.0f * bmpSize.dx / tileOnScreen.dx, 1.0f * bmpSize.dy / tileOnScreen.dy);

        SelectObject(bmpDC, hbmp);
        if (factor != 1.0f)
            StretchBlt(hdc, bounds.x, bounds.y, bounds.dx, bounds.dy,
                bmpDC, (int)(xSrc * factor), (int)(ySrc * factor),
                (int)(bounds.dx * factor), (int)(bounds.dy * factor), SRCCOPY);
        else
            BitBlt(hdc, bounds.x, bounds.y, bounds.dx, bounds.dy,
                bmpDC, xSrc, ySrc, SRCCOPY);

        DeleteDC(bmpDC);

#ifdef SHOW_TILE_LAYOUT
        HPEN pen = CreatePen(PS_SOLID, 1, RGB(0xff, 0xff, 0x00));
        HGDIOBJ oldPen = SelectObject(hdc, pen);
        PaintRect(hdc, bounds);
        DeletePen(SelectObject(hdc, oldPen));
#endif
    }

    if (entry->outOfDate) {
        if (renderOutOfDateCue)
            *renderOutOfDateCue = true;
        CrashIf(renderedReplacement && !*renderedReplacement);
    }

    DropCacheEntry(entry);
    return 0;
}
コード例 #14
0
ファイル: MuiControl.cpp プロジェクト: kindleStudy/sumatrapdf
// Requests the window to draw itself on a Graphics canvas.
// offX and offY is a position of this window within
// Graphics canvas (pos is relative to that offset)
void Control::Paint(Graphics *, int, int)
{
    CrashIf(!IsVisible());

}
コード例 #15
0
ファイル: Tabs.cpp プロジェクト: jingyu9575/sumatrapdf
static LRESULT CALLBACK TabBarProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, UINT_PTR uIdSubclass,
                                   DWORD_PTR dwRefData) {
    PAINTSTRUCT ps;
    HDC hdc;
    int index;
    LPTCITEM tcs;

    UNUSED(uIdSubclass);
    UNUSED(dwRefData);

    TabPainter* tab = (TabPainter*)GetWindowLongPtr(hwnd, GWLP_USERDATA);

    if (WM_NCDESTROY == msg) {
        RemoveWindowSubclass(GetParent(hwnd), TabBarParentProc, 0);
        RemoveWindowSubclass(hwnd, TabBarProc, 0);
        return DefSubclassProc(hwnd, msg, wp, lp);
    }

    switch (msg) {
        case WM_DESTROY:
            delete tab;
            SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)0);
            break;

        case TCM_INSERTITEM:
            index = (int)wp;
            tcs = (LPTCITEM)lp;
            CrashIf(!(TCIF_TEXT & tcs->mask));
            tab->Insert(index, tcs->pszText);
            if (index <= tab->selectedTabIdx)
                tab->selectedTabIdx++;
            tab->xClicked = -1;
            InvalidateRgn(hwnd, nullptr, FALSE);
            UpdateWindow(hwnd);
            break;

        case TCM_SETITEM:
            index = (int)wp;
            tcs = (LPTCITEM)lp;
            if (TCIF_TEXT & tcs->mask) {
                if (tab->Set(index, tcs->pszText)) {
                    tab->Invalidate(index);
                }
            }
            break;

        case TCM_DELETEITEM:
            index = (int)wp;
            if (tab->Delete(index)) {
                if (index < tab->selectedTabIdx) {
                    tab->selectedTabIdx--;
                } else if (index == tab->selectedTabIdx) {
                    tab->selectedTabIdx = -1;
                }
                tab->xClicked = -1;
                if (tab->Count()) {
                    InvalidateRgn(hwnd, nullptr, FALSE);
                    UpdateWindow(hwnd);
                }
            }
            break;

        case TCM_DELETEALLITEMS:
            tab->DeleteAll();
            tab->selectedTabIdx = -1;
            tab->highlighted = -1;
            tab->xClicked = -1;
            tab->xHighlighted = -1;
            break;

        case TCM_SETITEMSIZE:
            if (tab->Reshape(LOWORD(lp), HIWORD(lp))) {
                tab->xClicked = -1;
                if (tab->Count()) {
                    InvalidateRgn(hwnd, nullptr, FALSE);
                    UpdateWindow(hwnd);
                }
            }
            break;

        case TCM_GETCURSEL:
            return tab->selectedTabIdx;

        case TCM_SETCURSEL: {
            index = (int)wp;
            if (index >= tab->Count()) {
                return -1;
            }
            int previous = tab->selectedTabIdx;
            if (index != tab->selectedTabIdx) {
                tab->Invalidate(tab->selectedTabIdx);
                tab->Invalidate(index);
                tab->selectedTabIdx = index;
                UpdateWindow(hwnd);
            }
            return previous;
        }

        case WM_NCHITTEST: {
            if (!tab->inTitlebar || hwnd == GetCapture()) {
                return HTCLIENT;
            }
            POINT pt = {GET_X_LPARAM(lp), GET_Y_LPARAM(lp)};
            ScreenToClient(hwnd, &pt);
            if (-1 != tab->IndexFromPoint(pt.x, pt.y)) {
                return HTCLIENT;
            }
        }
            return HTTRANSPARENT;

        case WM_MOUSELEAVE:
            PostMessage(hwnd, WM_MOUSEMOVE, 0xFF, 0);
            return 0;

        case WM_MOUSEMOVE: {
            tab->mouseCoordinates = lp;

            if (0xff != wp) {
                TrackMouseLeave(hwnd);
            }

            bool inX = false;
            int hl = wp == 0xFF ? -1 : tab->IndexFromPoint(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), &inX);
            if (tab->isDragging && hl == -1) {
                // preserve the highlighted tab if it's dragged outside the tabs' area
                hl = tab->highlighted;
            }
            if (tab->highlighted != hl) {
                if (tab->isDragging) {
                    // send notification if the highlighted tab is dragged over another
                    WindowInfo* win = FindWindowInfoByHwnd(hwnd);
                    int tabNo = tab->highlighted;
                    uitask::Post([=] { TabNotification(win, T_DRAG, tabNo, hl); });
                }

                tab->Invalidate(hl);
                tab->Invalidate(tab->highlighted);
                tab->highlighted = hl;
            }
            int xHl = inX && !tab->isDragging ? hl : -1;
            if (tab->xHighlighted != xHl) {
                tab->Invalidate(xHl);
                tab->Invalidate(tab->xHighlighted);
                tab->xHighlighted = xHl;
            }
            if (!inX)
                tab->xClicked = -1;
        }
            return 0;

        case WM_LBUTTONDOWN:
            bool inX;
            tab->nextTab = tab->IndexFromPoint(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), &inX);
            if (inX) {
                // send request to close the tab
                WindowInfo* win = FindWindowInfoByHwnd(hwnd);
                int next = tab->nextTab;
                uitask::Post([=] { TabNotification(win, T_CLOSING, next, -1); });
            } else if (tab->nextTab != -1) {
                if (tab->nextTab != tab->selectedTabIdx) {
                    // send request to select tab
                    WindowInfo* win = FindWindowInfoByHwnd(hwnd);
                    uitask::Post([=] { TabNotification(win, TCN_SELCHANGING, -1, -1); });
                }
                tab->isDragging = true;
                SetCapture(hwnd);
            }
            return 0;

        case WM_LBUTTONUP:
            if (tab->xClicked != -1) {
                // send notification that the tab is closed
                WindowInfo* win = FindWindowInfoByHwnd(hwnd);
                int clicked = tab->xClicked;
                uitask::Post([=] { TabNotification(win, T_CLOSE, clicked, -1); });
                tab->Invalidate(clicked);
                tab->xClicked = -1;
            }
            if (tab->isDragging) {
                tab->isDragging = false;
                ReleaseCapture();
            }
            return 0;

        case WM_MBUTTONDOWN:
            // middle-clicking unconditionally closes the tab
            {
                tab->nextTab = tab->IndexFromPoint(GET_X_LPARAM(lp), GET_Y_LPARAM(lp));
                // send request to close the tab
                WindowInfo* win = FindWindowInfoByHwnd(hwnd);
                int next = tab->nextTab;
                uitask::Post([=] { TabNotification(win, T_CLOSING, next, -1); });
            }
            return 0;

        case WM_MBUTTONUP:
            if (tab->xClicked != -1) {
                // send notification that the tab is closed
                WindowInfo* win = FindWindowInfoByHwnd(hwnd);
                int clicked = tab->xClicked;
                uitask::Post([=] { TabNotification(win, T_CLOSE, clicked, -1); });
                tab->Invalidate(clicked);
                tab->xClicked = -1;
            }
            return 0;

        case WM_ERASEBKGND:
            return TRUE;

        case WM_PAINT: {
            RECT rc;
            GetUpdateRect(hwnd, &rc, FALSE);
            // TODO: when is wp != nullptr?
            hdc = wp ? (HDC)wp : BeginPaint(hwnd, &ps);

            DoubleBuffer buffer(hwnd, RectI::FromRECT(rc));
            tab->Paint(buffer.GetDC(), rc);
            buffer.Flush(hdc);

            ValidateRect(hwnd, nullptr);
            if (!wp)
                EndPaint(hwnd, &ps);
            return 0;
        }

        case WM_SIZE: {
            WindowInfo* win = FindWindowInfoByHwnd(hwnd);
            if (win)
                UpdateTabWidth(win);
        } break;
    }

    return DefSubclassProc(hwnd, msg, wp, lp);
}
コード例 #16
0
ファイル: TextRange.cpp プロジェクト: jra101/sumatrapdf
 // return false when cannot be moved
 virtual bool NextEndpoint() const {
     // HACK: Declaring these as pure virtual causes "unreferenced local variable" warnings ==> define a dummy body to get rid of warnings
     CrashIf(true);
     return false;
 }
コード例 #17
0
static void GetProps(Controller *ctrl, PropertiesLayout *layoutData, bool extended)
{
    CrashIf(!ctrl);

    WCHAR *str = str::Dup(gPluginMode ? gPluginURL : ctrl->FilePath());
    layoutData->AddProperty(_TR("File:"), str, true);

    str = ctrl->GetProperty(Prop_Title);
    layoutData->AddProperty(_TR("Title:"), str);

    str = ctrl->GetProperty(Prop_Subject);
    layoutData->AddProperty(_TR("Subject:"), str);

    str = ctrl->GetProperty(Prop_Author);
    layoutData->AddProperty(_TR("Author:"), str);

    str = ctrl->GetProperty(Prop_Copyright);
    layoutData->AddProperty(_TR("Copyright:"), str);

    str = ctrl->GetProperty(Prop_CreationDate);
    if (str && ctrl->AsFixed() && Engine_PDF == ctrl->AsFixed()->engineType)
        ConvDateToDisplay(&str, PdfDateParse);
    else
        ConvDateToDisplay(&str, IsoDateParse);
    layoutData->AddProperty(_TR("Created:"), str);

    str = ctrl->GetProperty(Prop_ModificationDate);
    if (str && ctrl->AsFixed() && Engine_PDF == ctrl->AsFixed()->engineType)
        ConvDateToDisplay(&str, PdfDateParse);
    else
        ConvDateToDisplay(&str, IsoDateParse);
    layoutData->AddProperty(_TR("Modified:"), str);

    str = ctrl->GetProperty(Prop_CreatorApp);
    layoutData->AddProperty(_TR("Application:"), str);

    str = ctrl->GetProperty(Prop_PdfProducer);
    layoutData->AddProperty(_TR("PDF Producer:"), str);

    str = ctrl->GetProperty(Prop_PdfVersion);
    layoutData->AddProperty(_TR("PDF Version:"), str);

    str = FormatPdfFileStructure(ctrl);
    layoutData->AddProperty(_TR("PDF Optimizations:"), str);

    int64 fileSize = file::GetSize(ctrl->FilePath());
    if (-1 == fileSize && ctrl->AsFixed()) {
        size_t fileSizeT;
        if (ScopedMem<unsigned char>(ctrl->AsFixed()->GetEngine()->GetFileData(&fileSizeT)))
            fileSize = fileSizeT;
    }
    if (-1 != fileSize) {
        str = FormatFileSize((size_t)fileSize);
        layoutData->AddProperty(_TR("File Size:"), str);
    }

    // TODO: display page count per current layout for ebooks?
    if (!ctrl->AsEbook()) {
        str = str::Format(L"%d", ctrl->PageCount());
        layoutData->AddProperty(_TR("Number of Pages:"), str);
    }

    if (ctrl->AsFixed()) {
        str = FormatPageSize(ctrl->AsFixed()->GetEngine(), ctrl->CurrentPageNo(), ctrl->AsFixed()->GetRotation());
        if (IsUIRightToLeft() && IsVistaOrGreater()) {
            // ensure that the size remains ungarbled left-to-right
            // (note: XP doesn't know about \u202A...\u202C)
            WCHAR *tmp = str;
            str = str::Format(L"\u202A%s\u202C", tmp);
            free(tmp);
        }
        layoutData->AddProperty(_TR("Page Size:"), str);
    }

    str = FormatPermissions(ctrl);
    layoutData->AddProperty(_TR("Denied Permissions:"), str);

#if defined(DEBUG) || defined(ENABLE_EXTENDED_PROPERTIES)
    if (extended) {
        // TODO: FontList extraction can take a while
        str = ctrl->GetProperty(Prop_FontList);
        if (str) {
            // add a space between basic and extended file properties
            layoutData->AddProperty(L" ", str::Dup(L" "));
        }
        layoutData->AddProperty(_TR("Fonts:"), str);
    }
#else
    UNUSED(extended);
#endif
}
コード例 #18
0
ファイル: TextRange.cpp プロジェクト: jra101/sumatrapdf
 virtual bool PrevEndpoint() const {
     CrashIf(true);
     return false;
 }
コード例 #19
0
ファイル: MuiFromText.cpp プロジェクト: Nargesf/Sumatrapdf
static TxtNode *GetRootArray(TxtParser* parser)
{
    TxtNode *root = parser->nodes.At(0);
    CrashIf(!root->IsArray());
    return root;
}
コード例 #20
0
void HwndWrapper::SetHwnd(HWND hwnd) {
    CrashIf(nullptr != hwndParent);
    hwndParent = hwnd;
    evtMgr = new EventMgr(this);
    painter = new Painter(this);
}
コード例 #21
0
EbookFormattingThread::EbookFormattingThread(Doc doc, HtmlFormatterArgs *args, EbookController *ctrl, int reparseIdx, ControllerCallback *cb) :
    doc(doc), formatterArgs(args), cb(cb), controller(ctrl), pageCount(0), reparseIdx(reparseIdx), pagesAfterReparseIdx(0)
{
    CrashIf(reparseIdx < 0);
    AssertCrash(doc.IsDocLoaded() || (doc.IsNone() && (nullptr != args->htmlStr)));
}
コード例 #22
0
ファイル: MuiScrollBar.cpp プロジェクト: Andy-Amoy/sumatrapdf
float PercFromInt(int total, int n) {
    CrashIf(n > total);
    if (0 == total)
        return 0.f;
    return (float)n / (float)total;
}
コード例 #23
0
ファイル: WindowInfo.cpp プロジェクト: miau/sumatrapdf
void LinkHandler::GotoLink(PageDestination *link)
{
    assert(owner && owner->linkHandler == this);
    if (!link)
        return;
    if (!engine())
        return;

    DisplayModel *dm = owner->dm;
    ScopedMem<WCHAR> path(link->GetDestValue());
    PageDestType type = link->GetDestType();
    if (Dest_ScrollTo == type) {
        // TODO: respect link->ld.gotor.new_window for PDF documents ?
        ScrollTo(link);
    }
    else if (Dest_LaunchURL == type) {
        if (!path)
            /* ignore missing URLs */;
        else if (!str::FindChar(path, ':')) {
            // treat relative URIs as file paths
            // LaunchFile will reject unsupported file types
            LaunchFile(path, NULL);
        }
        else {
            // LaunchBrowser will reject unsupported URI schemes
            LaunchBrowser(path);
        }
    }
    else if (Dest_LaunchEmbedded == type) {
        // open embedded PDF documents in a new window
        if (path && str::StartsWith(path.Get(), dm->FilePath())) {
            WindowInfo *newWin = FindWindowInfoByFile(path);
            if (!newWin) {
                LoadArgs args(path, owner);
                newWin = LoadDocument(args);
            }
            if (newWin)
                newWin->Focus();
        }
        // offer to save other attachments to a file
        else
            link->SaveEmbedded(LinkSaver(*owner, path));
    }
    else if (Dest_LaunchFile == type) {
        if (path) {
            // LaunchFile only opens files inside SumatraPDF
            // (except for allowed perceived file types)
            LaunchFile(path, link);
        }
    }
    // predefined named actions
    else if (Dest_NextPage == type)
        dm->GoToNextPage(0);
    else if (Dest_PrevPage == type)
        dm->GoToPrevPage(0);
    else if (Dest_FirstPage == type)
        dm->GoToFirstPage();
    else if (Dest_LastPage == type)
        dm->GoToLastPage();
    // Adobe Reader extensions to the spec, cf. http://www.tug.org/applications/hyperref/manual.html
    else if (Dest_FindDialog == type)
        PostMessage(owner->hwndFrame, WM_COMMAND, IDM_FIND_FIRST, 0);
    else if (Dest_FullScreen == type)
        PostMessage(owner->hwndFrame, WM_COMMAND, IDM_VIEW_PRESENTATION_MODE, 0);
    else if (Dest_GoBack == type)
        dm->Navigate(-1);
    else if (Dest_GoForward == type)
        dm->Navigate(1);
    else if (Dest_GoToPageDialog == type)
        PostMessage(owner->hwndFrame, WM_COMMAND, IDM_GOTO_PAGE, 0);
    else if (Dest_PrintDialog == type)
        PostMessage(owner->hwndFrame, WM_COMMAND, IDM_PRINT, 0);
    else if (Dest_SaveAsDialog == type)
        PostMessage(owner->hwndFrame, WM_COMMAND, IDM_SAVEAS, 0);
    else if (Dest_ZoomToDialog == type)
        PostMessage(owner->hwndFrame, WM_COMMAND, IDM_ZOOM_CUSTOM, 0);
    else
        CrashIf(Dest_None != type);
}
コード例 #24
0
void Post(UITask *task)
{
    CrashIf(!task);
    lf("posting %s", task->name);
    PostMessage(gTaskDispatchHwnd, WM_EXECUTE_TASK, 0, (LPARAM)task);
}
コード例 #25
0
void TextRenderGdiplus::SetFont(mui::CachedFont *font) {
    CrashIf(!font->font);
    currFont = font;
}
コード例 #26
0
BaseEngine *CreateEngine(bool enableEbookEngines, const WCHAR *filePath, PasswordUI *pwdUI, DocType *typeOut)
{
    CrashIf(!filePath);

    BaseEngine *engine = NULL;
    DocType engineType = Engine_None;
    bool sniff = false;
RetrySniffing:
    if (PdfEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_PDF) {
        engine = PdfEngine::CreateFromFile(filePath, pwdUI);
        engineType = Engine_PDF;
    } else if (XpsEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_XPS) {
        engine = XpsEngine::CreateFromFile(filePath);
        engineType = Engine_XPS;
    } else if (DjVuEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_DjVu) {
        engine = DjVuEngine::CreateFromFile(filePath);
        engineType = Engine_DjVu;
    } else if (ImageEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_Image) {
        engine = ImageEngine::CreateFromFile(filePath);
        engineType = Engine_Image;
    } else if (ImageDirEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_ImageDir) {
        engine = ImageDirEngine::CreateFromFile(filePath);
        engineType = Engine_ImageDir;
    } else if (CbxEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_ComicBook) {
        engine = CbxEngine::CreateFromFile(filePath);
        engineType = Engine_ComicBook;
    } else if (PsEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_PS) {
        engine = PsEngine::CreateFromFile(filePath);
        engineType = Engine_PS;
    } else if (ChmEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_Chm) {
        engine = ChmEngine::CreateFromFile(filePath);
        engineType = Engine_Chm;
    } else if (!enableEbookEngines) {
        // don't try to create any of the below ebook engines
    } else if (EpubEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_Epub) {
        engine = EpubEngine::CreateFromFile(filePath);
        engineType = Engine_Epub;
    } else if (Fb2Engine::IsSupportedFile(filePath, sniff) && engineType != Engine_Fb2) {
        engine = Fb2Engine::CreateFromFile(filePath);
        engineType = Engine_Fb2;
    } else if (MobiEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_Mobi) {
        engine = MobiEngine::CreateFromFile(filePath);
        engineType = Engine_Mobi;
    } else if (PdbEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_Pdb) {
        engine = PdbEngine::CreateFromFile(filePath);
        engineType = Engine_Pdb;
    } else if (Chm2Engine::IsSupportedFile(filePath, sniff) && engineType != Engine_Chm2) {
        engine = Chm2Engine::CreateFromFile(filePath);
        engineType = Engine_Chm2;
    } else if (TcrEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_Tcr) {
        engine = TcrEngine::CreateFromFile(filePath);
        engineType = Engine_Tcr;
    } else if (HtmlEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_Html) {
        engine = HtmlEngine::CreateFromFile(filePath);
        engineType = Engine_Html;
    } else if (TxtEngine::IsSupportedFile(filePath, sniff) && engineType != Engine_Txt) {
        engine = TxtEngine::CreateFromFile(filePath);
        engineType = Engine_Txt;
    }

    if (!engine && !sniff) {
        // try sniffing the file instead
        sniff = true;
        goto RetrySniffing;
    }
    CrashIf(engine && !IsSupportedFile(enableEbookEngines, filePath, sniff));

    if (typeOut)
        *typeOut = engine ? engineType : Engine_None;
    return engine;
}
コード例 #27
0
RectF TextRenderGdiplus::Measure(const char *s, size_t sLen) {
    CrashIf(!currFont);
    size_t strLen = str::Utf8ToWcharBuf(s, sLen, txtConvBuf, dimof(txtConvBuf));
    return MeasureText(gfx, currFont->font, txtConvBuf, strLen, measureAlgo);
}
コード例 #28
0
ファイル: Print.cpp プロジェクト: RazvanB/sumatrapdf
void OnMenuPrint(WindowInfo *win, bool waitForCompletion)
{
    // we remember some printer settings per process
    static ScopedMem<DEVMODE> defaultDevMode;
    static PrintScaleAdv defaultScaleAdv = PrintScaleShrink;
    static bool defaultAsImage = false;

    static bool hasDefaults = false;
    if (!hasDefaults) {
        hasDefaults = true;
        defaultAsImage = gGlobalPrefs->printerDefaults.printAsImage;
        if (str::EqI(gGlobalPrefs->printerDefaults.printScale, "fit"))
            defaultScaleAdv = PrintScaleFit;
        else if (str::EqI(gGlobalPrefs->printerDefaults.printScale, "none"))
            defaultScaleAdv = PrintScaleNone;
    }

    bool printSelection = false;
    Vec<PRINTPAGERANGE> ranges;
    PRINTER_INFO_2 printerInfo = { 0 };

    if (!HasPermission(Perm_PrinterAccess))
        return;

    if (win->AsChm()) {
        // the Print dialog allows access to the file system, so fall back
        // to printing the entire document without dialog if that isn't desired
        bool showUI = HasPermission(Perm_DiskAccess);
        win->AsChm()->PrintCurrentPage(showUI);
        return;
    }
    if (win->AsEbook()) {
        // TODO: use EbookEngine for printing?
        return;
    }

    CrashIf(!win->AsFixed());
    if (!win->AsFixed()) return;
    DisplayModel *dm = win->AsFixed();

#ifndef DISABLE_DOCUMENT_RESTRICTIONS
    if (!dm->engine()->AllowsPrinting())
        return;
#endif

    if (win->printThread) {
        int res = MessageBox(win->hwndFrame, 
                             _TR("Printing is still in progress. Abort and start over?"),
                             _TR("Printing in progress."),
                             MB_ICONEXCLAMATION | MB_YESNO | MbRtlReadingMaybe());
        if (res == IDNO)
            return;
    }
    AbortPrinting(win);

    // the Print dialog allows access to the file system, so fall back
    // to printing the entire document without dialog if that isn't desired
    if (!HasPermission(Perm_DiskAccess)) {
        PrintFile(dm->engine());
        return;
    }

    PRINTDLGEX pd;
    ZeroMemory(&pd, sizeof(PRINTDLGEX));
    pd.lStructSize = sizeof(PRINTDLGEX);
    pd.hwndOwner   = win->hwndFrame;
    pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE;
    if (!win->selectionOnPage)
        pd.Flags |= PD_NOSELECTION;
    pd.nCopies     = 1;
    /* by default print all pages */
    pd.nPageRanges = 1;
    pd.nMaxPageRanges = MAXPAGERANGES;
    PRINTPAGERANGE *ppr = AllocArray<PRINTPAGERANGE>(MAXPAGERANGES);
    pd.lpPageRanges = ppr;
    ppr->nFromPage = 1;
    ppr->nToPage = dm->PageCount();
    pd.nMinPage = 1;
    pd.nMaxPage = dm->PageCount();
    pd.nStartPage = START_PAGE_GENERAL;

    Print_Advanced_Data advanced(PrintRangeAll, defaultScaleAdv, defaultAsImage);
    ScopedMem<DLGTEMPLATE> dlgTemplate; // needed for RTL languages
    HPROPSHEETPAGE hPsp = CreatePrintAdvancedPropSheet(&advanced, dlgTemplate);
    pd.lphPropertyPages = &hPsp;
    pd.nPropertyPages = 1;

    // restore remembered settings
    if (defaultDevMode) {
        DEVMODE *p = defaultDevMode.Get();
        pd.hDevMode = GlobalMemDup(p, p->dmSize + p->dmDriverExtra);
    }

    if (PrintDlgEx(&pd) != S_OK) {
        if (CommDlgExtendedError() != 0) {
            /* if PrintDlg was cancelled then
               CommDlgExtendedError is zero, otherwise it returns the
               error code, which we could look at here if we wanted.
               for now just warn the user that printing has stopped
               becasue of an error */
            MessageBoxWarning(win->hwndFrame, _TR("Couldn't initialize printer"), 
                              _TR("Printing problem."));
        }
        goto Exit;
    }

    if (pd.dwResultAction == PD_RESULT_PRINT || pd.dwResultAction == PD_RESULT_APPLY) {
        // remember settings for this process
        LPDEVMODE devMode = (LPDEVMODE)GlobalLock(pd.hDevMode);
        if (devMode) {
            defaultDevMode.Set((LPDEVMODE)memdup(devMode, devMode->dmSize + devMode->dmDriverExtra));
            GlobalUnlock(pd.hDevMode);
        }
        defaultScaleAdv = advanced.scale;
        defaultAsImage = advanced.asImage;
    }

    if (pd.dwResultAction != PD_RESULT_PRINT)
        goto Exit;

    if (pd.Flags & PD_CURRENTPAGE) {
        PRINTPAGERANGE pr = { dm->CurrentPageNo(), dm->CurrentPageNo() };
        ranges.Append(pr);
    } else if (win->selectionOnPage && (pd.Flags & PD_SELECTION)) {
        printSelection = true;
    } else if (!(pd.Flags & PD_PAGENUMS)) {
        PRINTPAGERANGE pr = { 1, dm->PageCount() };
        ranges.Append(pr);
    } else {
        assert(pd.nPageRanges > 0);
        for (DWORD i = 0; i < pd.nPageRanges; i++)
            ranges.Append(pd.lpPageRanges[i]);
    }

    LPDEVNAMES devNames = (LPDEVNAMES)GlobalLock(pd.hDevNames);
    LPDEVMODE devMode = (LPDEVMODE)GlobalLock(pd.hDevMode);
    if (devNames) {
        printerInfo.pDriverName = (LPWSTR)devNames + devNames->wDriverOffset;
        printerInfo.pPrinterName = (LPWSTR)devNames + devNames->wDeviceOffset;
        printerInfo.pPortName = (LPWSTR)devNames + devNames->wOutputOffset;
    }
    PrintData *data = new PrintData(dm->engine(), &printerInfo, devMode, ranges, advanced,
                                    dm->GetRotation(), printSelection ? win->selectionOnPage : NULL);
    if (devNames)
        GlobalUnlock(pd.hDevNames);
    if (devMode)
        GlobalUnlock(pd.hDevMode);

    // if a file is missing and the engine can't thus be cloned,
    // we print using the original engine on the main thread
    // so that the document can't be closed and the original engine
    // unexpectedly deleted
    // TODO: instead prevent closing the document so that printing
    // can still happen on a separate thread and be interruptible
    bool failedEngineClone = dm->engine() && !data->engine;
    if (failedEngineClone)
        data->engine = dm->engine();

    if (!waitForCompletion && !failedEngineClone)
        PrintToDeviceOnThread(win, data);
    else {
        PrintToDevice(*data);
        if (failedEngineClone)
            data->engine = NULL;
        delete data;
    }

Exit:
    free(ppr);
    GlobalFree(pd.hDevNames);
    GlobalFree(pd.hDevMode);
}
コード例 #29
0
TextRenderGdi::~TextRenderGdi() {
    FreeMemBmp();
    DeleteDC(memHdc);
    ReleaseDC(nullptr, hdcForTextMeasure);
    CrashIf(hdcGfxLocked); // hasn't been Unlock()ed
}
コード例 #30
0
static BencDict *DisplayState_Serialize(DisplayState *ds, bool globalPrefsOnly)
{
    BencDict *prefs = new BencDict();
    if (!prefs)
        return NULL;

    prefs->Add(FILE_STR, ds->filePath);
    if (ds->decryptionKey)
        prefs->AddRaw(DECRYPTION_KEY_STR, ds->decryptionKey);

    prefs->Add(OPEN_COUNT_STR, ds->openCount);
    prefs->Add(IS_PINNED_STR, ds->isPinned);
    if (globalPrefsOnly || ds->useGlobalValues) {
        prefs->Add(USE_GLOBAL_VALUES_STR, TRUE);
        return prefs;
    }

    const WCHAR *mode = DisplayModeConv::NameFromEnum(ds->displayMode);
    prefs->Add(DISPLAY_MODE_STR, mode);
    prefs->Add(PAGE_NO_STR, ds->pageNo);
    prefs->Add(REPARSE_IDX_STR, ds->reparseIdx);
    prefs->Add(ROTATION_STR, ds->rotation);
    prefs->Add(SCROLL_X_STR, ds->scrollPos.x);
    prefs->Add(SCROLL_Y_STR, ds->scrollPos.y);
    prefs->Add(WINDOW_STATE_STR, ds->windowState);
    prefs->Add(WINDOW_X_STR, ds->windowPos.x);
    prefs->Add(WINDOW_Y_STR, ds->windowPos.y);
    prefs->Add(WINDOW_DX_STR, ds->windowPos.dx);
    prefs->Add(WINDOW_DY_STR, ds->windowPos.dy);

    prefs->Add(TOC_VISIBLE_STR, ds->tocVisible);
    prefs->Add(SIDEBAR_DX_STR, ds->sidebarDx);

    // BUG: 2140
    if (!IsValidZoom(ds->zoomVirtual)) {
        CrashLogFmt("Invalid ds->zoomVirtual: %.4f\n", ds->zoomVirtual);
        const WCHAR *ext = str::FindCharLast(ds->filePath, L'.');
        if (ext) {
            ScopedMem<char> extA(str::conv::ToUtf8(ext));
            CrashLogFmt("File type: %s\n", extA.Get());
        }
        CrashLogFmt("DisplayMode: %d\n", ds->displayMode);
        CrashLogFmt("PageNo: %d\n", ds->pageNo);
    }

    CrashIf(!IsValidZoom(ds->zoomVirtual));
    ScopedMem<char> zoom(str::Format("%.4f", ds->zoomVirtual));
    prefs->AddRaw(ZOOM_VIRTUAL_STR, zoom);

    if (ds->tocState && ds->tocState->Count() > 0) {
        BencArray *tocState = new BencArray();
        if (tocState) {
            for (size_t i = 0; i < ds->tocState->Count(); i++) {
                tocState->Add(ds->tocState->At(i));
            }
            prefs->Add(TOC_STATE_STR, tocState);
        }
    }

    return prefs;
}