void CDrawShapeView::OnFileSave() { if (m_filename.IsEmpty()) { CFileDialog dlg(FALSE, L".vg", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST, L"Shape files (*.vg)|*.vg||", this); if (dlg.DoModal() != IDOK) return; m_filename = dlg.GetPathName(); } MgJsonStorage s; shapes()->setZoomRectW(m_graph->xf.getWndRectW(), m_graph->xf.getViewScale()); if (shapes()->save(s.storageForWrite())) { const char* content = s.stringify(true); CFile file; if (file.Open(m_filename, CFile::modeWrite | CFile::modeCreate)) { file.Write(content, strlen(content)); } } else { AfxMessageBox(L"得到文件内容出错。"); } }
void CDrawShapeView::OnInitialUpdate() { if (!m_filename.IsEmpty()) { m_graph->xf.setModelTransform(shapes()->modelTransform()); m_graph->xf.zoomTo(shapes()->getZoomRectW()); m_graph->xf.zoomScale(shapes()->getViewScale()); OnZoomed(); } }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); cairo_translate (cr, 10, 10); /* simple clip */ cairo_save (cr); cairo_rectangle (cr, 0, 0, 20, 20); cairo_clip (cr); shapes (cr); cairo_restore (cr); cairo_translate (cr, WIDTH, 0); /* unaligned clip */ cairo_save (cr); cairo_rectangle (cr, 0.5, 0.5, 20, 20); cairo_clip (cr); shapes (cr); cairo_restore (cr); cairo_translate (cr, -WIDTH, HEIGHT); /* aligned-clip */ cairo_save (cr); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_rectangle (cr, 0, 0, 20, 20); cairo_rectangle (cr, 3, 3, 10, 10); cairo_rectangle (cr, 7, 7, 10, 10); cairo_clip (cr); shapes (cr); cairo_restore (cr); cairo_translate (cr, WIDTH, 0); /* force a clip-mask */ cairo_save (cr); cairo_arc (cr, 10, 10, 10, 0, 2 * M_PI); cairo_new_sub_path (cr); cairo_arc_negative (cr, 10, 10, 5, 2 * M_PI, 0); cairo_new_sub_path (cr); cairo_arc (cr, 10, 10, 2, 0, 2 * M_PI); cairo_clip (cr); shapes (cr); cairo_restore (cr); return CAIRO_TEST_SUCCESS; }
// Finds the index of the tab, which contains the given point. int IndexFromPoint(int x, int y, bool *inXbutton=nullptr) { Point point(x, y); Graphics graphics(hwnd); GraphicsPath shapes(data->Points, data->Types, data->Count); GraphicsPath shape; GraphicsPathIterator iterator(&shapes); iterator.NextMarker(&shape); ClientRect rClient(hwnd); REAL yPosTab = inTitlebar ? 0.0f : REAL(rClient.dy - height - 1); graphics.TranslateTransform(1.0f, yPosTab); for (int i = 0; i < Count(); i++) { Point pt(point); graphics.TransformPoints( CoordinateSpaceWorld, CoordinateSpaceDevice, &pt, 1); if (shape.IsVisible(pt, &graphics)) { iterator.NextMarker(&shape); if (inXbutton) *inXbutton = shape.IsVisible(pt, &graphics) ? true : false; return i; } graphics.TranslateTransform(REAL(width + 1), 0.0f); } if (inXbutton) *inXbutton = false; return -1; }
void test1() { QAxObject excel( "Excel.Application", 0); excel.setProperty("Visible", true); QAxObjectPtr workbooks(excel.querySubObject("Workbooks")); QAxObjectPtr workbook(workbooks->querySubObject("Add()")); QAxObjectPtr sheets(workbook->querySubObject("Worksheets")); sheets->dynamicCall("Add()"); QAxObjectPtr sheet(sheets->querySubObject( "Item( int )", 1 )); // sheet->setProperty("Name","Nova Planilha"); QAxObjectPtr range(sheet->querySubObject("Cells(int,int)",1,1)); range->setProperty("Value", QVariant(1234)); QImage image("c:/Users/jhlee/Dropbox/orgwiki/img/class01.png"); QClipboard* clip = QApplication::clipboard(); clip->setImage(image); QAxObjectPtr shapes(sheet->querySubObject("Shapes")); sheet->dynamicCall("Paste()"); int shapeCount = shapes->property("Count").toInt(); QAxObjectPtr shape(shapes->querySubObject(QString::fromLatin1("Item(%1)").arg(shapeCount).toAscii())); // shapes->dynamicCall("AddPicture( QString&, bool, bool, double, double, double, double","c:\\Users\\jhlee\\Dropbox\\orgwiki\\img\\class01.png",true,true,100,100,70,70); excel.setProperty("DisplayAlerts", false); workbook->dynamicCall("SaveAs(QString&)", "c:\\temp\\testexcel.xlsx"); // //workbook->dynamicCall("Close()"); // //excel.dynamicCall("Quit()"); // workbook->dynamicCall("Close (Boolean)", true); excel.dynamicCall("Quit()"); }
void GiCoreView::setContext(const GiContext& ctx, int mask, int apply) { DrawLocker locker(impl); if (mask != 0) { int n = impl->_cmds->getSelection(impl, 0, NULL, true); std::vector<MgShape*> shapes(n, (MgShape*)0); if (n > 0 && impl->_cmds->getSelection(impl, n, (MgShape**)&shapes.front(), true) > 0) { for (int i = 0; i < n; i++) { if (shapes[i]) { shapes[i]->context()->copy(ctx, mask); } } impl->redraw(); } else { impl->context()->copy(ctx, mask); } } if (apply != 0) { impl->_cmds->dynamicChangeEnded(impl, apply > 0); } }
SCPage::SCPage(SCDocument *document) : KoPAPage(document), d(new Private(this, document)) { setApplicationData(new SCPageApplicationData()); placeholders().init(0, shapes()); }
int MyShape::addShapeToList( shape_pointer insertShape ) { int curSize = shapes.size(); shapes.resize(curSize + 1); shapes(curSize) = insertShape; return curSize; }
void KTextDocumentLayout::documentChanged(int position, int charsRemoved, int charsAdded) { Q_UNUSED(charsRemoved); if (shapes().count() == 0) // nothing to do. return; /* switch (document()->documentLayout()->property("KoTextRelayoutForPage").toInt()) { case KTextShapeData::NormalState: kDebug() << "KoTextRelayoutForPage in NormalState"; break; case KTextShapeData::LayoutCopyShape: kDebug() << "KoTextRelayoutForPage in LayoutCopyShape"; break; case KTextShapeData::LayoutOrig: kDebug() << "KoTextRelayoutForPage in LayoutOrig, skipping relayout"; break; } */ if (document()->documentLayout()->property("KoTextRelayoutForPage").toInt() == KTextShapeData::LayoutOrig) { // don't refresh if we relayout after a relayout-for-page return; } int from = position; const int to = from + charsAdded; while (from < to) { // find blocks that have been added QTextBlock block = document()->findBlock(from); if (! block.isValid()) break; if (from == block.position() && block.textList()) { KTextBlockData *data = dynamic_cast<KTextBlockData*>(block.userData()); if (data) data->setCounterWidth(-1); // invalidate whole list. } from = block.position() + block.length(); } foreach (KShape *shape, shapes()) { KTextShapeData *data = qobject_cast<KTextShapeData*>(shape->userData()); Q_ASSERT(data); if (data && data->position() <= position && data->endPosition() >= position) { // found our (first) shape to re-layout data->foul(); m_state->interrupted = true; scheduleLayout(); return; } }
void KoPAMasterPage::paintPage( QPainter & painter, KoZoomHandler & zoomHandler ) { paintBackground( painter, zoomHandler ); KoShapePainter shapePainter; shapePainter.setShapes( shapes() ); shapePainter.paint(painter, zoomHandler); }
void SCPage::setLayout(SCPageLayout * layout, KoPADocument * document) { QSizeF pageSize(pageLayout().width, pageLayout().height); SCMasterPage * master = dynamic_cast<SCMasterPage *>(masterPage()); Q_ASSERT(master); placeholders().setLayout(layout, document, shapes(), pageSize, master ? master->placeholders().styles() : QMap<QString, KTextShapeData*>()); kDebug(33001) << "master placeholders"; master->placeholders().debug(); }
bool createSimulationFilter( PxRigidActor* actor, const PxFilterData& filter ) { if ( !actor ) return false; std::vector<PxShape*> shapes( actor->getNbShapes() ); PxU32 num = actor->getShapes( &(shapes[0]), actor->getNbShapes() ); for ( PxU32 i=0; i<num; ++i ) shapes[i]->setSimulationFilterData( filter ); return true; }
void KoPAPage::paintPage( QPainter & painter, KoZoomHandler & zoomHandler ) { paintBackground( painter, zoomHandler ); KoShapePainter shapePainter( getPaintingStrategy() ); if ( displayMasterShapes() ) { shapePainter.setShapes( masterPage()->shapes() ); shapePainter.paint(painter, zoomHandler); } shapePainter.setShapes( shapes() ); shapePainter.paint(painter, zoomHandler); }
QRectF KoShapeLayer::boundingRect() const { QRectF bb; Q_FOREACH (KoShape* shape, shapes()) { if (bb.isEmpty()) bb = shape->boundingRect(); else bb = bb.united(shape->boundingRect()); } return bb; }
bool KoShapePaste::process(const KoXmlElement & body, KoOdfReadStore & odfStore) { d->pastedShapes.clear(); KoOdfLoadingContext loadingContext(odfStore.styles(), odfStore.store()); KoShapeLoadingContext context(loadingContext, d->canvas->shapeController()->resourceManager()); QList<KoShape*> shapes(d->layer ? d->layer->shapes(): d->canvas->shapeManager()->topLevelShapes()); int zIndex = 0; if (!shapes.isEmpty()) { zIndex = shapes.first()->zIndex(); foreach (KoShape * shape, shapes) { zIndex = qMax(zIndex, shape->zIndex()); }
void KoPAPageBase::saveOdfLayers(KoPASavingContext &paContext) const { QList<KoShape*> shapes(this->shapes()); qSort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex); foreach(KoShape* shape, shapes) { KoShapeLayer *layer = dynamic_cast<KoShapeLayer*>(shape); if (layer) { paContext.addLayerForSaving(layer); } else { Q_ASSERT(layer); kWarning(30010) << "Page contains non layer where a layer is expected"; } }
QSizeF KoShapeGroup::size() const { Q_D(const KoShapeGroup); //debugFlake << "size" << d->size; if (!d->sizeCached) { QRectF bound; Q_FOREACH (KoShape *shape, shapes()) { if (bound.isEmpty()) bound = shape->transformation().mapRect(shape->outlineRect()); else bound |= shape->transformation().mapRect(shape->outlineRect()); } d->size = bound.size(); d->sizeCached = true; debugFlake << "recalculated size" << d->size; }
// Invalidates the tab's region in the client area. void Invalidate(int index) { if (index < 0) return; Graphics graphics(hwnd); GraphicsPath shapes(data->Points, data->Types, data->Count); GraphicsPath shape; GraphicsPathIterator iterator(&shapes); iterator.NextMarker(&shape); Region region(&shape); ClientRect rClient(hwnd); REAL yPosTab = inTitlebar ? 0.0f : REAL(rClient.dy - height - 1); graphics.TranslateTransform(REAL((width + 1) * index) + 1.0f, yPosTab); HRGN hRgn = region.GetHRGN(&graphics); InvalidateRgn(hwnd, hRgn, FALSE); DeleteObject(hRgn); }
static void prepare(KoShape *s, QMap<KoShape*, QList<KoShape*> > &newOrder, KoShapeManager *manager, KoShapeReorderCommand::MoveShapeType move) { KoShapeContainer *parent = s->parent(); QMap<KoShape*, QList<KoShape*> >::iterator it(newOrder.find(parent)); if (it == newOrder.end()) { QList<KoShape*> children; if (parent != 0) { children = parent->shapes(); } else { // get all toplevel shapes children = manager->topLevelShapes(); } qSort(children.begin(), children.end(), KoShape::compareShapeZIndex); // the append and prepend are needed so that the raise/lower of all shapes works as expected. children.append(0); children.prepend(0); it = newOrder.insert(parent, children); } QList<KoShape *> & shapes(newOrder[parent]); int index = shapes.indexOf(s); if (index != -1) { shapes.removeAt(index); switch (move) { case KoShapeReorderCommand::BringToFront: index = shapes.size(); break; case KoShapeReorderCommand::RaiseShape: if (index < shapes.size()) { ++index; } break; case KoShapeReorderCommand::LowerShape: if (index > 0) { --index; } break; case KoShapeReorderCommand::SendToBack: index = 0; break; } shapes.insert(index,s); } }
QDomDocument FolderShape::save() const { QDomDocument doc; QDomElement element = doc.createElement("book"); doc.appendChild(element); foreach (KShape *child, shapes()) { IconShape *ic = dynamic_cast<IconShape*>(child); if (ic) { ic->save(element); continue; } ClipboardProxyShape *proxy = dynamic_cast<ClipboardProxyShape*>(child); if (proxy) { QDomElement clipboard = doc.createElement("clipboard"); element.appendChild(clipboard); QDomText text = doc.createCDATASection( QString::fromAscii( proxy->clipboardData(), proxy->clipboardData().size() ) ); clipboard.appendChild(text); continue; } }
verdict test_randomized() { #if !defined(NO_RANDOMIZATION) srand (unsigned(get_time_stamp()/get_frequency())); // Randomize pseudo random number generator #endif std::cout << "=================== Randomized Test ===================" << std::endl; size_t a1 = 0, a2 = 0; std::vector<long long> mediansV(K); // Final verdict of medians for each of the K experiments with visitors std::vector<long long> mediansM(K); // Final verdict of medians for each of the K experiments with matching std::vector<long long> timingsV(M); std::vector<long long> timingsM(M); std::vector<Shape*> shapes(N); for (size_t k = 0; k < K; ++k) { for (size_t i = 0; i < N; ++i) shapes[i] = make_shape(rand()); run_timings(shapes, timingsV, timingsM, a1, a2); mediansV[k] = display("AreaVisRnd", timingsV); mediansM[k] = display("AreaMatRnd", timingsM); std::cout << "\t\t" << verdict(mediansV[k], mediansM[k]) << std::endl; for (size_t i = 0; i < N; ++i) { delete shapes[i]; shapes[i] = 0; } } if (a1 != a2) { std::cout << "ERROR: Invariant " << a1 << "==" << a2 << " doesn't hold." << std::endl; exit(42); } std::sort(mediansV.begin(), mediansV.end()); std::sort(mediansM.begin(), mediansM.end()); return verdict(mediansV[K/2],mediansM[K/2]); }
verdict test_repetitive() { std::cout << "=================== Repetitive Test ===================" << std::endl; size_t a1 = 0, a2 = 0; std::vector<long long> mediansV(K); // Final verdict of medians for each of the K experiments with visitors std::vector<long long> mediansM(K); // Final verdict of medians for each of the K experiments with matching std::vector<long long> timingsV(M); std::vector<long long> timingsM(M); std::vector<Shape*> shapes(N); for (size_t k = 0; k < K; ++k) { for (size_t i = 0; i < N; ++i) shapes[i] = make_shape((k+i)*2-k-2*i); run_timings(shapes, timingsV, timingsM, a1, a2); mediansV[k] = display("AreaVisRep", timingsV); mediansM[k] = display("AreaMatRep", timingsM); std::cout << "\t\t" << verdict(mediansV[k], mediansM[k]) << std::endl; for (size_t i = 0; i < N; ++i) { delete shapes[i]; shapes[i] = 0; } } if (a1 != a2) { std::cout << "ERROR: Invariant " << a1 << "==" << a2 << " doesn't hold." << std::endl; exit(42); } std::sort(mediansV.begin(), mediansV.end()); std::sort(mediansM.begin(), mediansM.end()); return verdict(mediansV[K/2],mediansM[K/2]); }
int main(){ int f[5][MAX/MIN_STEP] = {{0}}; for(int s = 0; s < 5; ++s){ for(int g = 1, n = 1; n <= MAX; g += s + 1, n += g){ if(n < MIN){ continue; } f[s][n/MIN_STEP] = n; } } char f3, f4, f5, f6, f1, boxcars, threes; int i1, i2; for(int g = 1, n = 1; n <= MAX; g += 6, n += g){ if(n < MIN){ continue; } i2 = n%100; for(int i3 = 10; i3 < 100; ++i3){ f3 = shapes(i2*100 + i3, f); if(!f3){ continue; } for(int i4 = 10; i4 < 100; ++i4){ f4 = shapes(i3*100 + i4, f); if(!f4){ continue; } for(int i5 = 10; i5 < 100; ++i5){ f5 = shapes(i4*100 + i5, f); if(!f5){ continue; } for(int i6 = 10; i6 < 100; ++i6){ f6 = shapes(i5*100 + i6, f); if(!f6){ continue; } i1 = n/100; f1 = shapes(i6*100 + i1, f); if(!f1){ continue; } if((f3 | f4 | f5 | f6 | f1) != 037){ continue; } boxcars = 0; if(f3 & 011){ f3 ^= 011; ++boxcars; } if(f4 & 011){ f4 ^= 011; ++boxcars; } if(f5 & 011){ f5 ^= 011; ++boxcars; } if(f6 & 011){ f6 ^= 011; ++boxcars; } if(f1 & 011){ f1 ^= 011; ++boxcars; } if(boxcars == 1){ threes = 0; if(f3 & 01){ ++threes; } if(f4 & 01){ ++threes; } if(f5 & 01){ ++threes; } if(f6 & 01){ ++threes; } if(f1 & 01){ ++threes; } if(!threes){ continue; } } printf("%i\n", 101*(i1 + i2 + i3 + i4 + i5 + i6)); return 0; } } } } } }
Foam::pointIndexHit Foam::octree<Type>::findLine ( const point& treeStart, const point& treeEnd ) const { // Initialize to a miss pointIndexHit hitInfo(false, treeStart, -1); const vector dir(treeEnd - treeStart); // Current line segment to search point start(treeStart); point end(treeEnd); while (true) { // Find nearest treeLeaf intersected by line point leafIntPoint; const treeLeaf<Type>* leafPtr = findLeafLine ( start, end, leafIntPoint ); if (!leafPtr) { // Reached end of string of treeLeaves to be searched. Return // whatever we have found so far. break; } // Inside treeLeaf find nearest intersection scalar minS = GREAT; const labelList& indices = leafPtr->indices(); forAll(indices, elemI) { label index = indices[elemI]; point pt; bool hit = shapes().intersects(index, start, end, pt); if (hit) { // Check whether intersection nearer p scalar s = (pt - treeStart) & dir; if (s < minS) { minS = s; // Update hit info hitInfo.setHit(); hitInfo.setPoint(pt); hitInfo.setIndex(index); // Update segment to search end = pt; } } } if (hitInfo.hit()) { // Found intersected shape. break; } // Start from end of current leaf start = leafIntPoint; }
bool simple_undo::modify (sxsdk::scene_interface *scene, void *) { // \en This plugin multiplies geometry attributes with 0.5. This is not a good way to scale shape objects, but we do it this way to show how undo works. \enden \ja このプラグインは、それぞれの形状の幾何属性に0.5を掛ける。形状を縮小する方法としては適切ではないが、アンドゥの機能をわかりやすくするために、このようにして幾何属性を変更する。 \endja scene->reset_undo_obsolete(); // \en Since we may register more than one undo action, call reset_undo() before registering any undo actions. \enden \ja ここでは一個以上のアンドゥアクションを登録するので、登録するまえにreset_undo()を呼ぶ。 \endja const int n = scene->get_active_shapes(0); if (0 < n) { std::vector<sxsdk::shape_class *> shapes(n); scene->get_active_shapes(&(shapes[0])); for (int i = 0; i < n; ++i) { sxsdk::shape_class &shape = *(shapes[i]); compointer<sxsdk::shape_saver_interface> shape_saver(shape.create_shape_saver_interface()); // \en Create a sxsdk::shape_saver_interface object. This object holds original geometry attributes. \enden \ja sxsdk::shape_saver_interfaceオブジェクトを生成する。このオブジェクトが元の形状の幾何属性を保持する。 \endja // \en Multilie geometry attributes with 0.5. \enden \ja 幾何属性に0.5を掛ける \endja switch (shape.get_type()) { case sxsdk::enums::polygon_mesh: { sxsdk::polygon_mesh_class &p = sxsdk::polygon_mesh_class::cast(shape); const int n = p.get_number_of_points(); for (int i = 0; i < n; ++i) { sxsdk::vertex_class &vertex = p.vertex(i); vertex.set_position(vertex.get_position() * 0.5f); } } break; case sxsdk::enums::line: { sxsdk::line_class &p = sxsdk::line_class::cast(shape); const int n = p.get_number_of_points(); for (int i = 0; i < n; ++i) { sxsdk::control_point_class &control_point = p.control_point(i); control_point.set_position(control_point.get_position() * 0.5f); } } break; case sxsdk::enums::part: { sxsdk::part_class &p = sxsdk::part_class::cast(shape); for (sxsdk::shape_class::iterator s = p.begin(); s != p.end(); ++s) { sxsdk::line_class &line = sxsdk::line_class::cast(*s); const int n = line.get_number_of_control_points(); for (int i = 0; i < n; ++i) { sxsdk::control_point_class &control_point = line.control_point(i); control_point.set_position(control_point.get_position() * 0.5f); } } } break; case sxsdk::enums::light: { sxsdk::light_class &p = sxsdk::light_class::cast(shape); p.set_intensity(p.get_intensity() * 0.5f); } break; case sxsdk::enums::sphere: { sxsdk::sphere_class &p = sxsdk::sphere_class::cast(shape); p.set_radius(p.get_radius() * 0.5f); } break; case sxsdk::enums::disk: { sxsdk::disk_class &p = sxsdk::disk_class::cast(shape); p.set_radius(p.get_radius() * 0.5f); } break; } shape_saver->set_undo_action(); // \en Register an undo action. \enden \ja アンドゥアクションを登録する。 \endja } } return true; }
// Paints the tabs that intersect the window's update rectangle. void Paint(HDC hdc, RECT &rc) { IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom); // paint the background bool isTranslucentMode = inTitlebar && dwm::IsCompositionEnabled(); if (isTranslucentMode) PaintParentBackground(hwnd, hdc); else { HBRUSH brush = CreateSolidBrush(color.bar); FillRect(hdc, &rc, brush); DeleteObject(brush); } // TODO: GDI+ doesn't seem to cope well with SetWorldTransform XFORM ctm = { 1.0, 0, 0, 1.0, 0, 0 }; SetWorldTransform(hdc, &ctm); Graphics graphics(hdc); graphics.SetCompositingMode(CompositingModeSourceCopy); graphics.SetCompositingQuality(CompositingQualityHighQuality); graphics.SetSmoothingMode(SmoothingModeHighQuality); graphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit); graphics.SetPageUnit(UnitPixel); GraphicsPath shapes(data->Points, data->Types, data->Count); GraphicsPath shape; GraphicsPathIterator iterator(&shapes); SolidBrush br(Color(0, 0, 0)); Pen pen(&br, 2.0f); Font f(hdc, GetDefaultGuiFont()); // TODO: adjust these constant values for DPI? RectF layout((REAL)DpiScaleX(hwnd,3), 1.0f, REAL(width - DpiScaleX(hwnd,20)), (REAL)height); StringFormat sf(StringFormat::GenericDefault()); sf.SetFormatFlags(StringFormatFlagsNoWrap); sf.SetLineAlignment(StringAlignmentCenter); sf.SetTrimming(StringTrimmingEllipsisCharacter); REAL yPosTab = inTitlebar ? 0.0f : REAL(ClientRect(hwnd).dy - height - 1); for (int i = 0; i < Count(); i++) { graphics.ResetTransform(); graphics.TranslateTransform(1.f + (REAL)(width + 1) * i - (REAL)rc.left, yPosTab - (REAL)rc.top); if (!graphics.IsVisible(0, 0, width + 1, height + 1)) continue; // in firefox style we only paint current and highlighed tabs // all other tabs only show bool onlyText = g_FirefoxStyle && !((current == i) || (highlighted == i)); if (onlyText) { #if 0 // we need to first paint the background with the same color as caption, // otherwise the text looks funny (because is transparent?) // TODO: what is the damn bg color of caption? bar is too light, outline is too dark Color bgColTmp; bgColTmp.SetFromCOLORREF(color.bar); { SolidBrush bgBr(bgColTmp); graphics.FillRectangle(&bgBr, layout); } bgColTmp.SetFromCOLORREF(color.outline); { SolidBrush bgBr(bgColTmp); graphics.FillRectangle(&bgBr, layout); } #endif // TODO: this is a hack. If I use no background and cleartype, the // text looks funny (is bold). // CompositingModeSourceCopy doesn't work with clear type // another option is to draw background before drawing text, but // I can't figure out what is the actual color of caption graphics.SetTextRenderingHint(TextRenderingHintAntiAliasGridFit); graphics.SetCompositingMode(CompositingModeSourceCopy); //graphics.SetCompositingMode(CompositingModeSourceOver); br.SetColor(ToColor(color.text)); graphics.DrawString(text.At(i), -1, &f, layout, &sf, &br); graphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit); continue; } COLORREF bgCol = color.background;; if (current == i) { bgCol = color.current; } else if (highlighted == i) { bgCol = color.highlight; } // ensure contrast between text and background color // TODO: adjust threshold (and try adjusting both current/background tabs) COLORREF textCol = color.text; float bgLight = GetLightness(bgCol), textLight = GetLightness(textCol); if (textLight < bgLight ? bgLight < 0x70 : bgLight > 0x90) textCol = textLight ? AdjustLightness(textCol, 255.0f / textLight - 1.0f) : RGB(255, 255, 255); if (fabs(textLight - bgLight) < 0x40) textCol = bgLight < 0x80 ? RGB(255, 255, 255) : RGB(0, 0, 0); // paint tab's body graphics.SetCompositingMode(CompositingModeSourceCopy); iterator.NextMarker(&shape); br.SetColor(ToColor(bgCol)); graphics.FillPath(&br, &shape); // draw tab's text graphics.SetCompositingMode(CompositingModeSourceOver); br.SetColor(ToColor(textCol)); graphics.DrawString(text.At(i), -1, &f, layout, &sf, &br); // paint "x"'s circle iterator.NextMarker(&shape); if (xClicked == i || xHighlighted == i) { br.SetColor(ToColor(i == xClicked ? color.x_click : color.x_highlight)); graphics.FillPath(&br, &shape); } // paint "x" iterator.NextMarker(&shape); if (xClicked == i || xHighlighted == i) pen.SetColor(ToColor(color.x_line)); else pen.SetColor(ToColor(color.outline)); graphics.DrawPath(&pen, &shape); iterator.Rewind(); } }
hkpRigidBody* MeshWeldingDemo::loadAndInitSimpleMesh(const hkVector4& position, hkpWorld* world, hkPackfileReader::AllocatedData*& allocatedData) { hkpRigidBody* mesh = loadRigidBodyFromXmlFile("Resources/Physics/Landscapes/weldtestmesh.xml" , allocatedData); mesh->setPosition(position); //HK_SET_OBJECT_COLOR((hkUlong)mesh->getCollidable(), hkColor::rgbFromChars(255, 255, 255, 128)); // RGBA HK_ASSERT(0xaf639541, mesh->getCollidable()->getShape()->getType() == HK_SHAPE_MOPP); const hkpMoppBvTreeShape* moppShape = static_cast<const hkpMoppBvTreeShape*>(mesh->getCollidable()->getShape()); hkpSimpleMeshShape* meshShape = (hkpSimpleMeshShape*)moppShape->getShapeCollection(); HK_ASSERT(0xaf639541, moppShape->getShapeCollection()->getType() == HK_SHAPE_TRIANGLE_COLLECTION); // Replace the mesh shape with an extendedMeshShape // hkpExtendedMeshShape* extShape = new hkpExtendedMeshShape(); hkpExtendedMeshShape::TrianglesSubpart part; part.m_numTriangleShapes = meshShape->m_triangles.getSize(); part.m_vertexBase = &meshShape->m_vertices[0](0); part.m_vertexStriding = sizeof(hkVector4); part.m_numVertices = meshShape->m_vertices.getSize(); part.m_extrusion.setZero4(); part.m_indexBase = meshShape->m_triangles.begin(); part.m_indexStriding = sizeof(meshShape->m_triangles[0]); part.m_stridingType = hkpExtendedMeshShape::INDICES_INT32; extShape->addTrianglesSubpart(part); hkpMoppCompilerInput mci; mci.m_enableChunkSubdivision = true; hkpMoppCode* newCode = hkpMoppUtility::buildCode( extShape,mci); hkpMoppBvTreeShape* newMopp = new hkpMoppBvTreeShape( extShape, newCode ); mesh->setShape(newMopp); extShape->removeReference(); newCode->removeReference(); newMopp->removeReference(); // // Setup welding for this object. // { extShape->setRadius(0); const WeldingVariant& variant = g_variants[m_variantId]; switch (variant.m_weldingType ) { case ONE_SIDED: { hkpMeshWeldingUtility::ShapeInfo info; info.m_transform = hkTransform::getIdentity(); info.m_shape = newMopp; hkLocalArray< hkpMeshWeldingUtility::ShapeInfo > shapes( 1 ); shapes.pushBack( info ); extShape->m_weldingType = hkpWeldingUtility::WELDING_TYPE_CLOCKWISE; hkpMeshWeldingUtility::computeWeldingInfo( hkTransform::getIdentity(), extShape, shapes, true, hkpMeshWeldingUtility::WINDING_IGNORE_CONSISTENCY ); break; } case TWO_SIDED: case TWO_SIDED_NO_TOIS: { extShape->computeWeldingInfo( newMopp, hkpWeldingUtility::WELDING_TYPE_TWO_SIDED ); break; } case NONE: { extShape->m_disableWelding = true; break; } case OLD_STYLE: { break; } } } world->addEntity(mesh); return mesh; }
void IntersectorShortStack::Process(World const& world) { // If something has been changed we need to rebuild BVH if (!m_bvh || world.has_changed() || world.GetStateChange() != ShapeImpl::kStateChangeNone) { if (m_bvh) { m_device->DeleteBuffer(m_gpudata->bvh); m_device->DeleteBuffer(m_gpudata->vertices); } // Check if we can allocate enough stack memory Calc::DeviceSpec spec; m_device->GetSpec(spec); if (spec.max_alloc_size <= kMaxBatchSize * kMaxStackSize * sizeof(int)) { throw ExceptionImpl("fatbvh accelerator can't allocate enough stack memory, try using bvh instead"); } int numshapes = (int)world.shapes_.size(); int numvertices = 0; int numfaces = 0; // This buffer tracks mesh start index for next stage as mesh face indices are relative to 0 std::vector<int> mesh_vertices_start_idx(numshapes); std::vector<int> mesh_faces_start_idx(numshapes); auto builder = world.options_.GetOption("bvh.builder"); auto splits = world.options_.GetOption("bvh.sah.use_splits"); auto maxdepth = world.options_.GetOption("bvh.sah.max_split_depth"); auto overlap = world.options_.GetOption("bvh.sah.min_overlap"); auto tcost = world.options_.GetOption("bvh.sah.traversal_cost"); auto node_budget = world.options_.GetOption("bvh.sah.extra_node_budget"); auto nbins = world.options_.GetOption("bvh.sah.num_bins"); bool use_sah = false; bool use_splits = false; int max_split_depth = maxdepth ? (int)maxdepth->AsFloat() : 10; int num_bins = nbins ? (int)nbins->AsFloat() : 64; float min_overlap = overlap ? overlap->AsFloat() : 0.05f; float traversal_cost = tcost ? tcost->AsFloat() : 10.f; float extra_node_budget = node_budget ? node_budget->AsFloat() : 0.5f; if (builder && builder->AsString() == "sah") { use_sah = true; } if (splits && splits->AsFloat() > 0.f) { use_splits = true; } m_bvh.reset(use_splits ? new SplitBvh(traversal_cost, num_bins, max_split_depth, min_overlap, extra_node_budget) : new Bvh(traversal_cost, num_bins, use_sah) ); // Partition the array into meshes and instances std::vector<Shape const*> shapes(world.shapes_); auto firstinst = std::partition(shapes.begin(), shapes.end(), [&](Shape const* shape) { return !static_cast<ShapeImpl const*>(shape)->is_instance(); }); // Count the number of meshes int nummeshes = (int)std::distance(shapes.begin(), firstinst); // Count the number of instances int numinstances = (int)std::distance(firstinst, shapes.end()); for (int i = 0; i < nummeshes; ++i) { Mesh const* mesh = static_cast<Mesh const*>(shapes[i]); mesh_faces_start_idx[i] = numfaces; mesh_vertices_start_idx[i] = numvertices; numfaces += mesh->num_faces(); numvertices += mesh->num_vertices(); } for (int i = nummeshes; i < nummeshes + numinstances; ++i) { Instance const* instance = static_cast<Instance const*>(shapes[i]); Mesh const* mesh = static_cast<Mesh const*>(instance->GetBaseShape()); mesh_faces_start_idx[i] = numfaces; mesh_vertices_start_idx[i] = numvertices; numfaces += mesh->num_faces(); numvertices += mesh->num_vertices(); } // We can't avoild allocating it here, since bounds aren't stored anywhere std::vector<bbox> bounds(numfaces); // We handle meshes first collecting their world space bounds #pragma omp parallel for for (int i = 0; i < nummeshes; ++i) { Mesh const* mesh = static_cast<Mesh const*>(shapes[i]); for (int j = 0; j < mesh->num_faces(); ++j) { // Here we directly get world space bounds mesh->GetFaceBounds(j, false, bounds[mesh_faces_start_idx[i] + j]); } } // Then we handle instances. Need to flatten them into actual geometry. #pragma omp parallel for for (int i = nummeshes; i < nummeshes + numinstances; ++i) { Instance const* instance = static_cast<Instance const*>(shapes[i]); Mesh const* mesh = static_cast<Mesh const*>(instance->GetBaseShape()); // Instance is using its own transform for base shape geometry // so we need to get object space bounds and transform them manually matrix m, minv; instance->GetTransform(m, minv); for (int j = 0; j < mesh->num_faces(); ++j) { bbox tmp; mesh->GetFaceBounds(j, true, tmp); bounds[mesh_faces_start_idx[i] + j] = transform_bbox(tmp, m); } } m_bvh->Build(&bounds[0], numfaces); #ifdef RR_PROFILE m_bvh->PrintStatistics(std::cout); #endif // Check if the tree height is reasonable if (m_bvh->GetHeight() >= kMaxStackSize) { m_bvh.reset(nullptr); throw ExceptionImpl("fatbvh accelerator can cause stack overflow for this scene, try using bvh instead"); } FatNodeBvhTranslator translator; translator.Process(*m_bvh); // Update GPU data // Create vertex buffer { // Vertices m_gpudata->vertices = m_device->CreateBuffer(numvertices * sizeof(float3), Calc::BufferType::kRead); // Get the pointer to mapped data float3* vertexdata = nullptr; Calc::Event* e = nullptr; m_device->MapBuffer(m_gpudata->vertices, 0, 0, numvertices * sizeof(float3), Calc::MapType::kMapWrite, (void**)&vertexdata, &e); e->Wait(); m_device->DeleteEvent(e); // Here we need to put data in world space rather than object space // So we need to get the transform from the mesh and multiply each vertex matrix m, minv; #pragma omp parallel for for (int i = 0; i < nummeshes; ++i) { // Get the mesh Mesh const* mesh = static_cast<Mesh const*>(shapes[i]); // Get vertex buffer of the current mesh float3 const* myvertexdata = mesh->GetVertexData(); // Get mesh transform mesh->GetTransform(m, minv); //#pragma omp parallel for // Iterate thru vertices multiply and append them to GPU buffer for (int j = 0; j < mesh->num_vertices(); ++j) { vertexdata[mesh_vertices_start_idx[i] + j] = transform_point(myvertexdata[j], m); } } #pragma omp parallel for for (int i = nummeshes; i < nummeshes + numinstances; ++i) { Instance const* instance = static_cast<Instance const*>(shapes[i]); // Get the mesh Mesh const* mesh = static_cast<Mesh const*>(instance->GetBaseShape()); // Get vertex buffer of the current mesh float3 const* myvertexdata = mesh->GetVertexData(); // Get mesh transform instance->GetTransform(m, minv); //#pragma omp parallel for // Iterate thru vertices multiply and append them to GPU buffer for (int j = 0; j < mesh->num_vertices(); ++j) { vertexdata[mesh_vertices_start_idx[i] + j] = transform_point(myvertexdata[j], m); } } m_device->UnmapBuffer(m_gpudata->vertices, 0, vertexdata, &e); e->Wait(); m_device->DeleteEvent(e); } // Create face buffer { // This number is different from the number of faces for some BVHs auto numindices = m_bvh->GetNumIndices(); std::vector<FatNodeBvhTranslator::Face> facedata(numindices); // Here the point is to add mesh starting index to actual index contained within the mesh, // getting absolute index in the buffer. // Besides that we need to permute the faces accorningly to BVH reordering, whihc // is contained within bvh.primids_ int const* reordering = m_bvh->GetIndices(); for (int i = 0; i < numindices; ++i) { int indextolook4 = reordering[i]; // We need to find a shape corresponding to current face auto iter = std::upper_bound(mesh_faces_start_idx.cbegin(), mesh_faces_start_idx.cend(), indextolook4); // Find the index of the shape int shapeidx = static_cast<int>(std::distance(mesh_faces_start_idx.cbegin(), iter) - 1); // Get the mesh directly or out of instance Mesh const* mesh = nullptr; if (shapeidx < nummeshes) { mesh = static_cast<Mesh const*>(shapes[shapeidx]); } else { mesh = static_cast<Mesh const*>(static_cast<Instance const*>(shapes[shapeidx])->GetBaseShape()); } // Get vertex buffer of the current mesh Mesh::Face const* myfacedata = mesh->GetFaceData(); // Find face idx int faceidx = indextolook4 - mesh_faces_start_idx[shapeidx]; // Find mesh start idx int mystartidx = mesh_vertices_start_idx[shapeidx]; // Copy face data to GPU buffer facedata[i].idx[0] = myfacedata[faceidx].idx[0] + mystartidx; facedata[i].idx[1] = myfacedata[faceidx].idx[1] + mystartidx; facedata[i].idx[2] = myfacedata[faceidx].idx[2] + mystartidx; facedata[i].shapeidx = shapes[shapeidx]->GetId(); facedata[i].shape_mask = shapes[shapeidx]->GetMask(); facedata[i].id = faceidx; } translator.InjectIndices(&facedata[0]); } // Copy translated nodes first m_gpudata->bvh = m_device->CreateBuffer(translator.nodes_.size() * sizeof(FatNodeBvhTranslator::Node), Calc::BufferType::kRead, &translator.nodes_[0]); // Stack m_gpudata->stack = m_device->CreateBuffer(kMaxBatchSize*kMaxStackSize, Calc::BufferType::kWrite); // Make sure everything is commited m_device->Finish(0); } }
bool FontContext::layoutText(TextStyle::Parameters& _params, const icu::UnicodeString& _text, std::vector<GlyphQuad>& _quads, std::bitset<max_textures>& _refs, glm::vec2& _size, TextRange& _textRanges) { std::lock_guard<std::mutex> lock(m_fontMutex); alfons::LineLayout line = m_shaper.shapeICU(_params.font, _text, MIN_LINE_WIDTH, _params.wordWrap ? _params.maxLineWidth : 0); if (line.missingGlyphs() || line.shapes().size() == 0) { // Nothing to do! return false; } line.setScale(_params.fontScale); // m_batch.drawShapeRange() calls FontContext's TextureCallback for new glyphs // and MeshCallback (drawGlyph) for vertex quads of each glyph in LineLayout. m_scratch.quads = &_quads; size_t quadsStart = _quads.size(); alfons::LineMetrics metrics; std::array<bool, 3> alignments = {}; if (_params.align != TextLabelProperty::Align::none) { alignments[int(_params.align)] = true; } // Collect possible alignment from anchor fallbacks for (int i = 0; i < _params.labelOptions.anchors.count; i++) { auto anchor = _params.labelOptions.anchors[i]; TextLabelProperty::Align alignment = TextLabelProperty::alignFromAnchor(anchor); if (alignment != TextLabelProperty::Align::none) { alignments[int(alignment)] = true; } } if (_params.wordWrap) { m_textWrapper.clearWraps(); if (_params.maxLines != 0) { uint32_t numLines = 0; int pos = 0; int max = line.shapes().size(); for (auto& shape : line.shapes()) { pos++; if (shape.mustBreak) { numLines++; if (numLines >= _params.maxLines && pos < max) { shape.mustBreak = false; line.removeShapes(shape.isSpace ? pos-1 : pos, max); auto ellipsis = m_shaper.shape(_params.font, "…"); line.addShapes(ellipsis.shapes()); break; } } } } float width = m_textWrapper.getShapeRangeWidth(line); for (size_t i = 0; i < 3; i++) { int rangeStart = m_scratch.quads->size(); if (!alignments[i]) { _textRanges[i] = Range(rangeStart, 0); continue; } int numLines = m_textWrapper.draw(m_batch, width, line, TextLabelProperty::Align(i), _params.lineSpacing, metrics); int rangeEnd = m_scratch.quads->size(); _textRanges[i] = Range(rangeStart, rangeEnd - rangeStart); // For single line text alignments are the same if (i == 0 && numLines == 1) { _textRanges[1] = Range(rangeEnd, 0); _textRanges[2] = Range(rangeEnd, 0); break; } } } else { glm::vec2 position(0); int rangeStart = m_scratch.quads->size(); m_batch.drawShapeRange(line, 0, line.shapes().size(), position, metrics); int rangeEnd = m_scratch.quads->size(); _textRanges[0] = Range(rangeStart, rangeEnd - rangeStart); _textRanges[1] = Range(rangeEnd, 0); _textRanges[2] = Range(rangeEnd, 0); } auto it = _quads.begin() + quadsStart; if (it == _quads.end()) { // No glyphs added return false; } // TextLabel parameter: Dimension float width = metrics.aabb.z - metrics.aabb.x; float height = metrics.aabb.w - metrics.aabb.y; _size = glm::vec2(width, height); // Offset to center all glyphs around 0/0 glm::vec2 offset((metrics.aabb.x + width * 0.5) * TextVertex::position_scale, (metrics.aabb.y + height * 0.5) * TextVertex::position_scale); { std::lock_guard<std::mutex> lock(m_textureMutex); for (; it != _quads.end(); ++it) { if (!_refs[it->atlas]) { _refs[it->atlas] = true; m_atlasRefCount[it->atlas]++; } it->quad[0].pos -= offset; it->quad[1].pos -= offset; it->quad[2].pos -= offset; it->quad[3].pos -= offset; } // Clear unused textures for (size_t i = 0; i < m_textures.size(); i++) { if (m_atlasRefCount[i] == 0) { m_atlas.clear(i); m_textures[i].texData.assign(GlyphTexture::size * GlyphTexture::size, 0); } } } return true; }
// Paints the tabs that intersect the window's update rectangle. void Paint(HDC hdc, RECT& rc) { IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom); // paint the background #if 0 bool isTranslucentMode = inTitlebar && dwm::IsCompositionEnabled(); if (isTranslucentMode) { PaintParentBackground(hwnd, hdc); } else { // note: not sure what color should be used here and painting // background works fine /*HBRUSH brush = CreateSolidBrush(colors.bar); FillRect(hdc, &rc, brush); DeleteObject(brush);*/ } #else PaintParentBackground(hwnd, hdc); #endif // TODO: GDI+ doesn't seem to cope well with SetWorldTransform XFORM ctm = {1.0, 0, 0, 1.0, 0, 0}; SetWorldTransform(hdc, &ctm); Graphics gfx(hdc); gfx.SetCompositingMode(CompositingModeSourceCopy); gfx.SetCompositingQuality(CompositingQualityHighQuality); gfx.SetSmoothingMode(SmoothingModeHighQuality); gfx.SetTextRenderingHint(TextRenderingHintClearTypeGridFit); gfx.SetPageUnit(UnitPixel); GraphicsPath shapes(data->Points, data->Types, data->Count); GraphicsPath shape; GraphicsPathIterator iterator(&shapes); SolidBrush br(Color(0, 0, 0)); Pen pen(&br, 2.0f); Font f(hdc, GetDefaultGuiFont()); // TODO: adjust these constant values for DPI? RectF layout((REAL)DpiScaleX(hwnd, 3), 1.0f, REAL(width - DpiScaleX(hwnd, 20)), (REAL)height); StringFormat sf(StringFormat::GenericDefault()); sf.SetFormatFlags(StringFormatFlagsNoWrap); sf.SetLineAlignment(StringAlignmentCenter); sf.SetTrimming(StringTrimmingEllipsisCharacter); REAL yPosTab = inTitlebar ? 0.0f : REAL(ClientRect(hwnd).dy - height - 1); for (int i = 0; i < Count(); i++) { gfx.ResetTransform(); gfx.TranslateTransform(1.f + (REAL)(width + 1) * i - (REAL)rc.left, yPosTab - (REAL)rc.top); if (!gfx.IsVisible(0, 0, width + 1, height + 1)) continue; // Get the correct colors based on the state and the current theme COLORREF bgCol = GetAppColor(AppColor::TabBackgroundBg); COLORREF textCol = GetAppColor(AppColor::TabBackgroundText); COLORREF xColor = GetAppColor(AppColor::TabBackgroundCloseX); COLORREF circleColor = GetAppColor(AppColor::TabBackgroundCloseCircle); if (selectedTabIdx == i) { bgCol = GetAppColor(AppColor::TabSelectedBg); textCol = GetAppColor(AppColor::TabSelectedText); xColor = GetAppColor(AppColor::TabSelectedCloseX); circleColor = GetAppColor(AppColor::TabSelectedCloseCircle); } else if (highlighted == i) { bgCol = GetAppColor(AppColor::TabHighlightedBg); textCol = GetAppColor(AppColor::TabHighlightedText); xColor = GetAppColor(AppColor::TabHighlightedCloseX); circleColor = GetAppColor(AppColor::TabHighlightedCloseCircle); } if (xHighlighted == i) { xColor = GetAppColor(AppColor::TabHoveredCloseX); circleColor = GetAppColor(AppColor::TabHoveredCloseCircle); } if (xClicked == i) { xColor = GetAppColor(AppColor::TabClickedCloseX); circleColor = GetAppColor(AppColor::TabClickedCloseCircle); } // paint tab's body gfx.SetCompositingMode(CompositingModeSourceCopy); iterator.NextMarker(&shape); br.SetColor(ToColor(bgCol)); Point points[4]; shape.GetPathPoints(points, 4); Rect body(points[0].X, points[0].Y, points[2].X - points[0].X, points[2].Y - points[0].Y); body.Inflate(0, 0); gfx.SetClip(body); body.Inflate(5, 5); gfx.FillRectangle(&br, body); gfx.ResetClip(); // draw tab's text gfx.SetCompositingMode(CompositingModeSourceOver); br.SetColor(ToColor(textCol)); gfx.DrawString(text.at(i), -1, &f, layout, &sf, &br); // paint "x"'s circle iterator.NextMarker(&shape); bool closeCircleEnabled = true; if ((xClicked == i || xHighlighted == i) && closeCircleEnabled) { br.SetColor(ToColor(circleColor)); gfx.FillPath(&br, &shape); } // paint "x" iterator.NextMarker(&shape); pen.SetColor(ToColor(xColor)); gfx.DrawPath(&pen, &shape); iterator.Rewind(); } }