int Pdfsync::DocToSource(UINT pageNo, PointI pt, ScopedMem<WCHAR>& filename, UINT *line, UINT *col) { if (IsIndexDiscarded()) if (RebuildIndex() != PDFSYNCERR_SUCCESS) return PDFSYNCERR_SYNCFILE_CANNOT_BE_OPENED; // find the entry in the index corresponding to this page if (pageNo <= 0 || pageNo >= sheetIndex.Count() || pageNo > (UINT)engine->PageCount()) return PDFSYNCERR_INVALID_PAGE_NUMBER; // PdfSync coordinates are y-inversed RectI mbox = engine->PageMediabox(pageNo).Round(); pt.y = mbox.dy - pt.y; // distance to the closest pdf location (in the range <PDFSYNC_EPSILON_SQUARE) UINT closest_xydist = UINT_MAX; UINT selected_record = UINT_MAX; // If no record is found within a distance^2 of PDFSYNC_EPSILON_SQUARE // (selected_record == -1) then we pick up the record that is closest // vertically to the hit-point. UINT closest_ydist = UINT_MAX; // vertical distance between the hit point and the vertically-closest record UINT closest_xdist = UINT_MAX; // horizontal distance between the hit point and the vertically-closest record UINT closest_ydist_record = UINT_MAX; // vertically-closest record // read all the sections of 'p' declarations for this pdf sheet for (size_t i = sheetIndex.At(pageNo); i < points.Count() && points.At(i).page == pageNo; i++) { // check whether it is closer than the closest point found so far UINT dx = abs(pt.x - (int)SYNC_TO_PDF_COORDINATE(points.At(i).x)); UINT dy = abs(pt.y - (int)SYNC_TO_PDF_COORDINATE(points.At(i).y)); UINT dist = dx * dx + dy * dy; if (dist < PDFSYNC_EPSILON_SQUARE && dist < closest_xydist) { selected_record = points.At(i).record; closest_xydist = dist; } else if ((closest_xydist == UINT_MAX) && dy < PDFSYNC_EPSILON_Y && (dy < closest_ydist || (dy == closest_ydist && dx < closest_xdist))) { closest_ydist_record = points.At(i).record; closest_ydist = dy; closest_xdist = dx; } } if (selected_record == UINT_MAX) selected_record = closest_ydist_record; if (selected_record == UINT_MAX) return PDFSYNCERR_NO_SYNC_AT_LOCATION; // no record was found close enough to the hit point // We have a record number, we need to find its declaration ('l ...') in the syncfile PdfsyncLine cmp; cmp.record = selected_record; PdfsyncLine *found = (PdfsyncLine *)bsearch(&cmp, lines.LendData(), lines.Count(), sizeof(PdfsyncLine), cmpLineRecords); assert(found); if (!found) return PDFSYNCERR_NO_SYNC_AT_LOCATION; filename.Set(str::Dup(srcfiles.At(found->file))); *line = found->line; *col = found->column; return PDFSYNCERR_SUCCESS; }
// transfers the data to a thread that does the actual sending static void QueueMessageForSending(Vec<byte>& msg) { size_t len = msg.Size(); if (0 == len) return; MemBlock *block = GetBlock(len); if (block) { block->Append(msg.LendData(), len); SetEvent(gSendThreadEvent); } else { lf("memtrace.dll: QueueMessageForSending() couldn't queu %d bytes", (int)len); } }
void VerticalLayout::Arrange(const Rect finalRect) { DirectionalLayoutData * e; SizeInfo * si; Vec<SizeInfo> sizes; for (e = els.IterStart(); e; e = els.IterNext()) { SizeInfo sizeInfo = { e->desiredSize.Height, e->sizeLayoutAxis, 0, 0 }; sizes.Append(sizeInfo); } RedistributeSizes(sizes.LendData(), sizes.Count(), finalRect.Height); for (e = els.IterStart(), si = sizes.IterStart(); e; e = els.IterNext(), si = sizes.IterNext()) { int dx = CalcScaledClippedSize(finalRect.Width, e->sizeNonLayoutAxis, e->desiredSize.Width); int x = e->alignNonLayoutAxis.CalcOffset(dx, finalRect.Width); e->element->Arrange(Rect(x, si->finalPos, dx, si->finalSize)); } }
static void VecTest() { Vec<int> ints; assert(ints.Count() == 0); ints.Append(1); ints.Push(2); ints.InsertAt(0, -1); assert(ints.Count() == 3); assert(ints.At(0) == -1 && ints.At(1) == 1 && ints.At(2) == 2); assert(ints.At(0) == -1 && ints.Last() == 2); int last = ints.Pop(); assert(last == 2); assert(ints.Count() == 2); ints.Push(3); ints.RemoveAt(0); assert(ints.Count() == 2); assert(ints.At(0) == 1 && ints.At(1) == 3); ints.Reset(); assert(ints.Count() == 0); for (int i = 0; i < 1000; i++) { ints.Push(i); } assert(ints.Count() == 1000 && ints.At(500) == 500); ints.Remove(500); assert(ints.Count() == 999 && ints.At(500) == 501); last = ints.Pop(); assert(last == 999); ints.Append(last); assert(ints.AtPtr(501) == &ints.At(501)); { Vec<int> ints2(ints); assert(ints2.Count() == 999); assert(ints.LendData() != ints2.LendData()); ints.Remove(600); assert(ints.Count() < ints2.Count()); ints2 = ints; assert(ints2.Count() == 998); } { char buf[2] = {'a', '\0'}; str::Str<char> v(0); for (int i = 0; i < 7; i++) { v.Append(buf, 1); buf[0] = buf[0] + 1; } char *s = v.LendData(); assert(str::Eq("abcdefg", s)); assert(7 == v.Count()); v.Set("helo"); assert(4 == v.Count()); assert(str::Eq("helo", v.LendData())); } { str::Str<char> v(128); v.Append("boo", 3); assert(str::Eq("boo", v.LendData())); assert(v.Count() == 3); v.Append("fop"); assert(str::Eq("boofop", v.LendData())); assert(v.Count() == 6); v.RemoveAt(2, 3); assert(v.Count() == 3); assert(str::Eq("bop", v.LendData())); v.Append('a'); assert(v.Count() == 4); assert(str::Eq("bopa", v.LendData())); char *s = v.StealData(); assert(str::Eq("bopa", s)); free(s); assert(v.Count() == 0); } { str::Str<char> v(0); for (int i = 0; i < 32; i++) { assert(v.Count() == i * 6); v.Append("lambd", 5); if (i % 2 == 0) v.Append('a'); else v.Push('a'); } for (int i=1; i<=16; i++) { v.RemoveAt((16 - i) * 6, 6); assert(v.Count() == (32 - i) * 6); } v.RemoveAt(0, 6 * 15); assert(v.Count() == 6); char *s = v.LendData(); assert(str::Eq(s, "lambda")); s = v.StealData(); assert(str::Eq(s, "lambda")); free(s); assert(v.Count() == 0); v.Append("lambda"); assert(str::Eq(v.LendData(), "lambda")); char c = v.Pop(); assert(c == 'a'); assert(str::Eq(v.LendData(), "lambd")); } VecTestAppendFmt(); { Vec<PointI *> v; srand((unsigned int)time(NULL)); for (int i = 0; i < 128; i++) { v.Append(new PointI(i, i)); size_t pos = rand() % v.Count(); v.InsertAt(pos, new PointI(i, i)); } assert(v.Count() == 128 * 2); size_t idx = 0; for (PointI **p = v.IterStart(); p; p = v.IterNext()) { assert(idx == v.IterIdx()); ++idx; } while (v.Count() > 64) { size_t pos = rand() % v.Count(); PointI *f = v.At(pos); v.Remove(f); delete f; } DeleteVecMembers(v); } { Vec<int> v; v.Append(2); for (int i = 0; i < 500; i++) v.Append(4); v.At(250) = 5; v.Reverse(); assert(v.Count() == 501 && v.At(0) == 4 && v.At(249) == v.At(251) && v.At(250) == 5 && v.At(500) == 2); v.Remove(4); v.Reverse(); assert(v.Count() == 500 && v.At(0) == 2 && v.At(249) == v.At(251) && v.At(250) == 5 && v.At(499) == 4); } }
WCHAR *EbookEngine::ExtractPageText(int pageNo, WCHAR *lineSep, RectI **coords_out, RenderTarget target) { ScopedCritSec scope(&pagesAccess); str::Str<WCHAR> content; Vec<RectI> coords; bool insertSpace = false; Vec<DrawInstr> *pageInstrs = GetHtmlPage(pageNo); for (DrawInstr *i = pageInstrs->IterStart(); i; i = pageInstrs->IterNext()) { RectI bbox = GetInstrBbox(i, pageBorder); switch (i->type) { case InstrString: if (coords.Count() > 0 && bbox.x < coords.Last().BR().x) { content.Append(lineSep); coords.AppendBlanks(str::Len(lineSep)); CrashIf(*lineSep && !coords.Last().IsEmpty()); } else if (insertSpace && coords.Count() > 0) { int swidth = bbox.x - coords.Last().BR().x; if (swidth > 0) { content.Append(' '); coords.Append(RectI(bbox.x - swidth, bbox.y, swidth, bbox.dy)); } } insertSpace = false; { ScopedMem<WCHAR> s(str::conv::FromHtmlUtf8(i->str.s, i->str.len)); content.Append(s); size_t len = str::Len(s); double cwidth = 1.0 * bbox.dx / len; for (size_t k = 0; k < len; k++) coords.Append(RectI((int)(bbox.x + k * cwidth), bbox.y, (int)cwidth, bbox.dy)); } break; case InstrRtlString: if (coords.Count() > 0 && bbox.BR().x > coords.Last().x) { content.Append(lineSep); coords.AppendBlanks(str::Len(lineSep)); CrashIf(*lineSep && !coords.Last().IsEmpty()); } else if (insertSpace && coords.Count() > 0) { int swidth = coords.Last().x - bbox.BR().x; if (swidth > 0) { content.Append(' '); coords.Append(RectI(bbox.BR().x, bbox.y, swidth, bbox.dy)); } } insertSpace = false; { ScopedMem<WCHAR> s(str::conv::FromHtmlUtf8(i->str.s, i->str.len)); content.Append(s); size_t len = str::Len(s); double cwidth = 1.0 * bbox.dx / len; for (size_t k = 0; k < len; k++) coords.Append(RectI((int)(bbox.x + (len - k - 1) * cwidth), bbox.y, (int)cwidth, bbox.dy)); } break; case InstrElasticSpace: case InstrFixedSpace: insertSpace = true; break; } } if (coords_out) { CrashIf(coords.Count() != content.Count()); *coords_out = new RectI[coords.Count()]; memcpy(*coords_out, coords.LendData(), coords.Count() * sizeof(RectI)); } return content.StealData(); }