void ImageButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) { if (! isEnabled()) { isMouseOverButton = false; isButtonDown = false; } Image im (getCurrentImage()); if (im.isValid()) { const int iw = im.getWidth(); const int ih = im.getHeight(); int w = getWidth(); int h = getHeight(); int x = (w - iw) / 2; int y = (h - ih) / 2; if (scaleImageToFit) { if (preserveProportions) { int newW, newH; const float imRatio = ih / (float) iw; const float destRatio = h / (float) w; if (imRatio > destRatio) { newW = roundToInt (h / imRatio); newH = h; } else { newW = w; newH = roundToInt (w * imRatio); } x = (w - newW) / 2; y = (h - newH) / 2; w = newW; h = newH; } else { x = 0; y = 0; } } if (! scaleImageToFit) { w = iw; h = ih; } imageBounds.setBounds (x, y, w, h); const bool useDownImage = isButtonDown || getToggleState(); getLookAndFeel().drawImageButton (g, &im, x, y, w, h, useDownImage ? downOverlay : (isMouseOverButton ? overOverlay : normalOverlay), useDownImage ? downOpacity : (isMouseOverButton ? overOpacity : normalOpacity), *this); } }
void OldSchoolLookAndFeel::drawScrollbar (Graphics& g, ScrollBar& bar, int x, int y, int width, int height, bool isScrollbarVertical, int thumbStartPosition, int thumbSize, bool isMouseOver, bool isMouseDown) { g.fillAll (bar.findColour (ScrollBar::backgroundColourId)); g.setColour (bar.findColour (ScrollBar::thumbColourId) .withAlpha ((isMouseOver || isMouseDown) ? 0.4f : 0.15f)); if (thumbSize > 0.0f) { Rectangle thumb; if (isScrollbarVertical) { width -= 2; g.fillRect (x + roundToInt (width * 0.35f), y, roundToInt (width * 0.3f), height); thumb.setBounds (x + 1, thumbStartPosition, width - 2, thumbSize); } else { height -= 2; g.fillRect (x, y + roundToInt (height * 0.35f), width, roundToInt (height * 0.3f)); thumb.setBounds (thumbStartPosition, y + 1, thumbSize, height - 2); } g.setColour (bar.findColour (ScrollBar::thumbColourId) .withAlpha ((isMouseOver || isMouseDown) ? 0.95f : 0.7f)); g.fillRect (thumb); g.setColour (Colours::black.withAlpha ((isMouseOver || isMouseDown) ? 0.4f : 0.25f)); g.drawRect (thumb.getX(), thumb.getY(), thumb.getWidth(), thumb.getHeight()); if (thumbSize > 16) { for (int i = 3; --i >= 0;) { const float linePos = thumbStartPosition + thumbSize / 2 + (i - 1) * 4.0f; g.setColour (Colours::black.withAlpha (0.15f)); if (isScrollbarVertical) { g.drawLine (x + width * 0.2f, linePos, width * 0.8f, linePos); g.setColour (Colours::white.withAlpha (0.15f)); g.drawLine (width * 0.2f, linePos - 1, width * 0.8f, linePos - 1); } else { g.drawLine (linePos, height * 0.2f, linePos, height * 0.8f); g.setColour (Colours::white.withAlpha (0.15f)); g.drawLine (linePos - 1, height * 0.2f, linePos - 1, height * 0.8f); } } } } }
void wjetsAsymmetrieEstimator(double luminosity = 36.1, bool save = false, bool textoutput=true, TString dataFile="./diffXSecFromSignal/data/DiffXSecData_Nov15PF.root", TString jetType = "PF") { // --- // main function parameters // --- // save: choose whether you want to save every plot as eps and all within one ps file // textoutput: choose whether you want to save the estimated number of QCD events for data // in .txt file to share it with other parts of the Analysis // luminosity: choose luminosity for scaling of event numbers // lum is derived from this and used for legend as entry TString lum = getTStringFromInt(roundToInt(luminosity)); // choose target directory for saving TString saveTo = "./diffXSecFromSignal/plots/chargeAsymmetrie/"; // choose whether you want to load c.a. parameter from crossSection.txt file // when writing into file, R is also taken from file bool loadR = false; if(textoutput) loadR=true; TString file = "crossSectionCalculation"+jetType+".txt"; // --- // set root style // --- gROOT->cd(); gROOT->SetStyle("Plain"); gStyle->SetErrorX(0); // --- // open input files // --- std::vector<TFile*> files_; TString whichSample = "/analysisRootFiles"; files_.push_back(new TFile("./diffXSecFromSignal"+whichSample+"/muonDiffXSecWjetsMadD6TFall10"+jetType+".root" ) ); files_.push_back(new TFile("./diffXSecFromSignal/analysisRootFiles/Fall10PseudoData7TeV"+getTStringFromInt((int)luminosity)+"pb.root" ) ); files_.push_back(new TFile("./diffXSecFromSignal/analysisRootFiles/Fall10PseudoData7TeV"+lum+"pb.root" ) ); files_.push_back(new TFile(dataFile ) ); files_.push_back(new TFile("./diffXSecFromSignal"+whichSample+"/muonDiffXSecAllMadD6TFall10"+jetType+".root" ) ); //files_.push_back(new TFile("./diffXSecFromSignal"+whichSample+"/muonDiffXSecAllNloSpring10.root" ) ); // create container for the different histos std::map< TString, std::map <unsigned int, TH1F*> > ptMuPlus_, ptMuMinus_, pt_; // example: ptMuPlus_[kWjets]["Njets1"] // ------------------------------------ // create jet multiplicity indicator std::vector<TString> Njets_; TString jets[ 4 ] = { "Njets1", "Njets2", "Njets3", "Njets4" }; Njets_.insert( Njets_.begin(), jets, jets + 4 ); // --- // get histograms // --- // loop jet multiplicities for(unsigned int mult=0; mult<4; ++mult){ // loop input files (W, all MC, data) for(int idx=kWjets; idx<=kTtbar; ++idx){ // pt(mu+/-) ptMuPlus_ [Njets_[mult]][idx] = (TH1F*)(files_[idx]->Get("analyzeTightMuonCrossSectionRec"+Njets_[mult]+"/ptPlus" ))->Clone(); ptMuMinus_[Njets_[mult]][idx] = (TH1F*)(files_[idx]->Get("analyzeTightMuonCrossSectionRec"+Njets_[mult]+"/ptMinus"))->Clone(); // pt(all mu) as mu+ + mu- pt_[Njets_[mult]][idx] = (TH1F*)ptMuPlus_ [Njets_[mult]][idx]->Clone(); pt_[Njets_[mult]][idx]->Add( (TH1F*)ptMuMinus_[Njets_[mult]][idx]->Clone() ); } } // --- // scale MC prediction to data luminosity // --- // a) fall10 7TeV W+jets MADGRAPH D6T sample double lumiweight=0.105750913/50*luminosity; // loop jet multiplicities for(unsigned int mult=0; mult<4; ++mult){ ptMuPlus_ [Njets_[mult]][kWjets]->Scale(lumiweight); ptMuMinus_[Njets_[mult]][kWjets]->Scale(lumiweight); pt_ [Njets_[mult]][kWjets]->Scale(lumiweight); } // b) fall10 7TeV TTbar MADGRAPH D6T sample double lumiweight2=0.006029022/50*luminosity; // loop jet multiplicities for(unsigned int mult=0; mult<4; ++mult){ ptMuPlus_ [Njets_[mult]][kTtbar]->Scale(lumiweight2); ptMuMinus_[Njets_[mult]][kTtbar]->Scale(lumiweight2); pt_ [Njets_[mult]][kTtbar]->Scale(lumiweight2); } // c) for pseudo data double lumiweight3=luminosity/50.0; // loop jet multiplicities for(unsigned int mult=0; mult<4; ++mult){ ptMuPlus_ [Njets_[mult]][kPseudo50]->Scale(lumiweight3); ptMuMinus_[Njets_[mult]][kPseudo50]->Scale(lumiweight3); pt_ [Njets_[mult]][kPseudo50]->Scale(lumiweight3); } // check weighting std::cout << "" << std::endl; std::cout << "check weighting W+jets MC (Njets>=4)" << std::endl; std::cout << "N(W) before weighting: " << pt_[Njets_[3]][kWjets]->GetEntries() << std::endl; double weightedEntries = sumUpEntries(*pt_[Njets_[3]][kWjets]); std::cout << "N(W) after weighting: " << weightedEntries << std::endl; std::cout << "ratio : " << weightedEntries/(double)(pt_[Njets_[3]][kWjets]->GetEntries()) << std::endl; std::cout << "weight: " << lumiweight << std::endl; // check pseudo data read out std::cout << "" << std::endl; std::cout << "check pseudo data N(jets)>=4" << std::endl; std::cout << "N = " << sumUpEntries(*pt_ [Njets_[3]][kPseudo50]) << std::endl; std::cout << "N+ = " << sumUpEntries(*ptMuPlus_ [Njets_[3]][kPseudo50]) << std::endl; std::cout << "N- = " << sumUpEntries(*ptMuMinus_[Njets_[3]][kPseudo50]) << std::endl; // print out important informations std::cout << std::endl << "w+jets estimation details:" << std::endl; std::cout << "- used R(pt(mu)>=20 GeV) from W->(mu && tau->mu)+jets gen niveau" << std::endl; std::cout << "- R is expected to have no error" << std::endl; std::cout << "- to test the method, the estimation is done from combined pseudo" << std::endl; std::cout << " data reco files (wjets+zjets+qcd+ttbar)" << std::endl; std::cout << " and from W+jets sample only" << std::endl; std::cout << "- additionally the estimation is done for real data" << std::endl<< std::endl; // --- // Apply the charge asymmetry method // --- // create c.a. estimation, MC truth and all events [N(jets)] histos TH1F *wjetsEstimationW = new TH1F("wjetsEstimationW" , "wjetsEstimationW" , 4, 0.5, 4.5); TH1F *wjetsEstimationAll = new TH1F("wjetsEstimationAll" , "wjetsEstimationAll", 4, 0.5, 4.5); TH1F *wjetsTruth = new TH1F("wjetsTruth" , "wjetsTruth" , 4, 0.5, 4.5); TH1F *allPseudoEvents = new TH1F("allPseudoEvents" , "allPseudoEvents" , 4, 0.5, 4.5); TH1F *wjetsData = new TH1F("wjetsData" , "wjetsData" , 4, 0.5, 4.5); // loop samples (W+jets, pseudo data, real data) for(unsigned int idx=kWjets; idx<=kData; ++idx){ // print out info for c.a. estimation if(idx==kWjets )std::cout << std::endl << "a) estimation from W+jets MC only:" << std::endl << std::endl; if(idx==kPseudo50)std::cout << std::endl << "b) estimation from pseudo data (all MC):" << std::endl << std::endl; if(idx==kData )std::cout << std::endl << "c) estimation within data:" << std::endl << std::endl; // loop jet multiplicities for(int njets=1; njets<=4; ++njets){ // a) charge asymmetry estimation std::cout << "---------------------" << std::endl << std::endl; std::cout << "N(jets) >= " << njets << std::endl; std::cout << "" << std::endl; double x = sumUpEntries(*ptMuPlus_ [Njets_[njets-1]][idx]); double y = sumUpEntries(*ptMuMinus_[Njets_[njets-1]][idx]); double R =getChargeAsymmetrieParameter(njets,loadR).first; double dR=getChargeAsymmetrieParameter(njets,loadR).second; // calculate entries for W+jets-estimation double NW = (x-y)*R; // calculate error for W+jets-estimation via gaussian error calculus double NWError = R*sqrt(NW); // print out results std::cout << "N(mu+)= " << x << std::endl; std::cout << "N(mu-)= " << y << std::endl; std::cout << "R(Njets >=" << njets << ") = " << R << " +- " << dR << std::endl; std::cout << "N(estimated W) = " << NW << " +- " << NWError << std::endl; std::cout << "N(W, MC truth) = " << sumUpEntries(*pt_[Njets_[njets-1]][kWjets]) << std::endl; double ratio = NW/(sumUpEntries(*pt_[Njets_[njets-1]][kWjets])); double ratioError = NWError/(sumUpEntries(*pt_[Njets_[njets-1]][kWjets])); std::cout << "ratio NWest/NWMC = " << ratio << " +/- " << ratioError << std::endl; std::cout << "total # of events: " << sumUpEntries(*pt_[Njets_[njets-1]][idx]) << std::endl; // b) fill wjetsEstimationW histo if(idx==kWjets){ wjetsEstimationW->SetBinContent( njets, NW); wjetsEstimationW->SetBinError ( njets, NWError); } // c) fill wjetsEstimationAll histo if(idx==kPseudo50){ wjetsEstimationAll->SetBinContent( njets, NW); wjetsEstimationAll->SetBinError ( njets, NWError); } // d) fill wjetsTruth histo if(idx==kWjets) wjetsTruth->SetBinContent( njets, sumUpEntries(*pt_[Njets_[njets-1]][kWjets]) ); // e) fill allPseudoEvents histo if(idx==kPseudo50) allPseudoEvents->SetBinContent( njets, ratio ); // f) fill data estimation histo if(idx==kData) wjetsData->SetBinContent( njets, sumUpEntries(*pt_[Njets_[njets-1]][kPseudo50]) ); // g) if textoutput==true: save W+jets data estimation within .txt-file if(textoutput==true&&idx==kData){ if(njets==1) writeToFile("estimated N(W) in Data using charge asymmetry method with R from above for N(jets) >= 1 - 4",file); writeToFile((x-y)*R,file); } } } // --- // create legends // --- // create a legend for estimation TLegend *leg0 = new TLegend(0.30, 0.69, 0.92, 0.94); leg0->SetFillStyle(0); leg0->SetBorderSize(0); leg0->SetHeader("N_{W} @ "+lum+" pb^{-1} ( 7 TeV )"); leg0->AddEntry( wjetsTruth , "MC truth" , "L" ); leg0->AddEntry( wjetsEstimationW , "estimation from W#rightarrowl#nu MC" , "PL"); leg0->AddEntry( wjetsEstimationAll, "estimation from pseudo data (all MC)", "PL"); // leg0->AddEntry( allPseudoEvents , "total # pseudo events" , "L" ); // create a legend for mu, mu+ and mu- of Ttar TLegend *leg1 = new TLegend(0.47, 0.68, 1.0, 0.93); leg1->SetFillStyle(0); leg1->SetBorderSize(0); leg1->SetHeader("t#bar{t}: "+lum+" pb^{-1}, N(jets) #geq 1" ); leg1->AddEntry( pt_ [Njets_[0]][kTtbar], "all #mu" , "L"); leg1->AddEntry( ptMuPlus_ [Njets_[0]][kTtbar], "#mu^{+}" , "L"); leg1->AddEntry( ptMuMinus_[Njets_[0]][kTtbar], "#mu^{-}" , "L"); // create a legend for mu, mu+ and mu- of Ttar TLegend *leg2 = new TLegend(0.47, 0.68, 1.0, 0.93); leg2->SetFillStyle(0); leg2->SetBorderSize(0); leg2->SetHeader("W+jets: "+lum+" pb^{-1}, N(jets) #geq 1" ); leg2->AddEntry( pt_ [Njets_[0]][kWjets], "all #mu" , "L"); leg2->AddEntry( ptMuPlus_ [Njets_[0]][kWjets], "#mu^{+}" , "L"); leg2->AddEntry( ptMuMinus_[Njets_[0]][kWjets], "#mu^{-}" , "L"); // --- // do the printing for N_W [Njets] // --- TCanvas* canv0 = new TCanvas("canv0", "canv0", 600, 600); canvasStyle(*canv0); // draw canvas canv0->cd(0); canv0->SetLogy(1); canv0->SetTitle("wjetsCAEstimation"+lum+"pb"); axesStyle(*wjetsTruth, "N_{jets} #geq", "N_{W}", 1., 10000000/50*luminosity); histogramStyle(*wjetsTruth , kGreen, 1, 20, 0.5); histogramStyle(*wjetsEstimationW , kBlue , 1, 23, 1.8); histogramStyle(*wjetsEstimationAll, kRed , 1, 22, 1.8); histogramStyle(*allPseudoEvents , kBlack, 2, 20, 0.5); wjetsTruth ->Draw(""); // allPseudoEvents ->Draw("same"); wjetsEstimationAll->Draw("esame"); wjetsEstimationW ->Draw("esame"); leg0 ->Draw("same"); // --- // do the printing for mu, mu+ and mu- for Top and W+jets // --- // a ) Top TCanvas* canv1 = new TCanvas("canv1", "canv1", 600, 600); canvasStyle(*canv1); // draw canvas canv1->cd(0); canv1->SetTitle("TopNjets1MuonCharge"+lum+"pb"); axesStyle(*pt_[Njets_[0]][kTtbar], "p_{t} (#mu)", "N_{t#bar{t}}", 0., 1.2*pt_[Njets_[0]][kTtbar]->GetMaximum(), 0.05, 1.3); histogramStyle(*ptMuPlus_ [Njets_[0]][kTtbar], kBlue , 2, 20, 0.5); histogramStyle(*ptMuMinus_[Njets_[0]][kTtbar], kRed , 3, 20, 0.5); histogramStyle(*pt_ [Njets_[0]][kTtbar], kBlack, 1, 20, 0.5); pt_ [Njets_[0]][kTtbar]->Draw(""); ptMuMinus_[Njets_[0]][kTtbar]->Draw("same"); ptMuPlus_ [Njets_[0]][kTtbar]->Draw("same"); leg1 ->Draw("same"); // b ) W+jets TCanvas* canv2 = new TCanvas("canv2", "canv2", 600, 600); canvasStyle(*canv2); // draw canvas canv2->cd(0); canv2->SetTitle("WjetsNjets1MuonCharge"+lum+"pb"); axesStyle(*pt_[Njets_[0]][kWjets], "p_{t} (#mu)", "N_{W}", 0., 1.2*pt_[Njets_[0]][kWjets]->GetMaximum(), 0.05, 1.3); histogramStyle(*ptMuPlus_ [Njets_[0]][kWjets], kBlue , 2, 20, 0.5); histogramStyle(*ptMuMinus_[Njets_[0]][kWjets], kRed , 3, 20, 0.5); histogramStyle(*pt_ [Njets_[0]][kWjets], kBlack, 1, 20, 0.5); pt_ [Njets_[0]][kWjets]->Draw(""); ptMuMinus_[Njets_[0]][kWjets]->Draw("same"); ptMuPlus_ [Njets_[0]][kWjets]->Draw("same"); leg2 ->Draw("same"); // --- // saving // --- if(save){ // ps canv0->Print(saveTo+"chargeAsymmetrieEstimation.ps(" ); canv1->Print(saveTo+"chargeAsymmetrieEstimation.ps" ); canv2->Print(saveTo+"chargeAsymmetrieEstimation.ps)" ); // eps canv0->Print(saveTo+(TString)(canv0->GetTitle())+".eps"); canv1->Print(saveTo+(TString)(canv1->GetTitle())+".eps"); canv2->Print(saveTo+(TString)(canv2->GetTitle())+".eps"); } }
void ListMarkerPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) { if (paintInfo.phase != PaintPhaseForeground) return; if (m_layoutListMarker.style()->visibility() != VISIBLE) return; if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_layoutListMarker, paintInfo.phase, paintOffset)) return; LayoutPoint boxOrigin(paintOffset + m_layoutListMarker.location()); LayoutRect overflowRect(m_layoutListMarker.visualOverflowRect()); overflowRect.moveBy(boxOrigin); IntRect pixelSnappedOverflowRect = pixelSnappedIntRect(overflowRect); if (!paintInfo.cullRect().intersectsCullRect(overflowRect)) return; LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutListMarker, paintInfo.phase, pixelSnappedOverflowRect, paintOffset); LayoutRect box(boxOrigin, m_layoutListMarker.size()); IntRect marker = m_layoutListMarker.getRelativeMarkerRect(); marker.moveBy(roundedIntPoint(boxOrigin)); GraphicsContext& context = paintInfo.context; if (m_layoutListMarker.isImage()) { context.drawImage(m_layoutListMarker.image()->image( &m_layoutListMarker, marker.size(), m_layoutListMarker.styleRef().effectiveZoom()).get(), marker); if (m_layoutListMarker.getSelectionState() != SelectionNone) { LayoutRect selRect = m_layoutListMarker.localSelectionRect(); selRect.moveBy(boxOrigin); context.fillRect(pixelSnappedIntRect(selRect), m_layoutListMarker.listItem()->selectionBackgroundColor()); } return; } LayoutListMarker::ListStyleCategory styleCategory = m_layoutListMarker.listStyleCategory(); if (styleCategory == LayoutListMarker::ListStyleCategory::None) return; const Color color(m_layoutListMarker.resolveColor(CSSPropertyColor)); // Apply the color to the list marker text. context.setFillColor(color); const EListStyleType listStyle = m_layoutListMarker.style()->listStyleType(); if (styleCategory == LayoutListMarker::ListStyleCategory::Symbol) { paintSymbol(context, color, marker, listStyle); return; } if (m_layoutListMarker.text().isEmpty()) return; const Font& font = m_layoutListMarker.style()->font(); TextRun textRun = constructTextRun(font, m_layoutListMarker.text(), m_layoutListMarker.styleRef()); GraphicsContextStateSaver stateSaver(context, false); if (!m_layoutListMarker.style()->isHorizontalWritingMode()) { marker.moveBy(roundedIntPoint(-boxOrigin)); marker = marker.transposedRect(); marker.moveBy(IntPoint(roundToInt(box.x()), roundToInt(box.y() - m_layoutListMarker.logicalHeight()))); stateSaver.save(); context.translate(marker.x(), marker.maxY()); context.rotate(static_cast<float>(deg2rad(90.))); context.translate(-marker.x(), -marker.maxY()); } TextRunPaintInfo textRunPaintInfo(textRun); textRunPaintInfo.bounds = marker; IntPoint textOrigin = IntPoint(marker.x(), marker.y() + m_layoutListMarker.style()->fontMetrics().ascent()); // Text is not arbitrary. We can judge whether it's RTL from the first character, // and we only need to handle the direction RightToLeft for now. bool textNeedsReversing = WTF::Unicode::direction(m_layoutListMarker.text()[0]) == WTF::Unicode::RightToLeft; StringBuilder reversedText; if (textNeedsReversing) { unsigned length = m_layoutListMarker.text().length(); reversedText.reserveCapacity(length); for (int i = length - 1; i >= 0; --i) reversedText.append(m_layoutListMarker.text()[i]); ASSERT(reversedText.length() == length); textRun.setText(reversedText.toString()); } const UChar suffix = ListMarkerText::suffix(listStyle, m_layoutListMarker.listItem()->value()); UChar suffixStr[2] = { suffix, static_cast<UChar>(' ') }; TextRun suffixRun = constructTextRun(font, suffixStr, 2, m_layoutListMarker.styleRef(), m_layoutListMarker.style()->direction()); TextRunPaintInfo suffixRunInfo(suffixRun); suffixRunInfo.bounds = marker; if (m_layoutListMarker.style()->isLeftToRightDirection()) { context.drawText(font, textRunPaintInfo, textOrigin); context.drawText(font, suffixRunInfo, textOrigin + IntSize(font.width(textRun), 0)); } else { context.drawText(font, suffixRunInfo, textOrigin); context.drawText(font, textRunPaintInfo, textOrigin + IntSize(font.width(suffixRun), 0)); } }
void MidiKeyboardComponent::resized() { int w = getWidth(); int h = getHeight(); if (w > 0 && h > 0) { if (orientation != horizontalKeyboard) std::swap (w, h); blackNoteLength = roundToInt (h * 0.7f); int kx2, kw2; getKeyPos (rangeEnd, kx2, kw2); kx2 += kw2; if ((int) firstKey != rangeStart) { int kx1, kw1; getKeyPos (rangeStart, kx1, kw1); if (kx2 - kx1 <= w) { firstKey = (float) rangeStart; sendChangeMessage(); repaint(); } } const bool showScrollButtons = canScroll && (((int) firstKey) > rangeStart || kx2 > w + xOffset * 2); scrollDown->setVisible (showScrollButtons); scrollUp->setVisible (showScrollButtons); xOffset = 0; if (showScrollButtons) { const int scrollButtonW = jmin (12, w / 2); if (orientation == horizontalKeyboard) { scrollDown->setBounds (0, 0, scrollButtonW, getHeight()); scrollUp->setBounds (getWidth() - scrollButtonW, 0, scrollButtonW, getHeight()); } else if (orientation == verticalKeyboardFacingLeft) { scrollDown->setBounds (0, 0, getWidth(), scrollButtonW); scrollUp->setBounds (0, getHeight() - scrollButtonW, getWidth(), scrollButtonW); } else { scrollDown->setBounds (0, getHeight() - scrollButtonW, getWidth(), scrollButtonW); scrollUp->setBounds (0, 0, getWidth(), scrollButtonW); } int endOfLastKey, kw; getKeyPos (rangeEnd, endOfLastKey, kw); endOfLastKey += kw; float mousePositionVelocity; const int spaceAvailable = w - scrollButtonW * 2; const int lastStartKey = remappedXYToNote (Point<int> (endOfLastKey - spaceAvailable, 0), mousePositionVelocity) + 1; if (lastStartKey >= 0 && ((int) firstKey) > lastStartKey) { firstKey = (float) jlimit (rangeStart, rangeEnd, lastStartKey); sendChangeMessage(); } int newOffset = 0; getKeyPos (((int) firstKey), newOffset, kw); xOffset = newOffset - scrollButtonW; } else { firstKey = (float) rangeStart; } repaint(); } }
int SystemStats::getCpuSpeedInMegaherz() { return roundToInt (LinuxStatsHelpers::getCpuInfo ("cpu MHz").getFloatValue()); }
int getLatency (AudioSessionPropertyID propID) { Float32 latency = 0; getSessionProperty (propID, latency); return roundToInt (latency * getCurrentSampleRate()); }
void resized() { marker.setBounds (0, roundToInt ((getHeight() - edge * 2) * h), getWidth(), edge * 2); }
void RenderMathMLRoot::paint(PaintInfo& info, const LayoutPoint& paintOffset) { RenderMathMLBlock::paint(info, paintOffset); if (info.context->paintingDisabled() || style().visibility() != VISIBLE) return; IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location() + contentBoxRect().location()); int startX = adjustedPaintOffset.x(); int frontWidth = lroundf(gFrontWidthEms * style().fontSize()); int overbarWidth = roundToInt(contentLogicalWidth()) + m_overbarLeftPointShift; int baseHeight = roundToInt(contentLogicalHeight()); int rootPad = lroundf(gSpaceAboveEms * style().fontSize()); adjustedPaintOffset.setY(adjustedPaintOffset.y() - rootPad); float radicalDipLeftPointYPos = (index() ? gRootRadicalDipLeftPointYPos : gSqrtRadicalDipLeftPointYPos) * baseHeight; FloatPoint overbarLeftPoint(startX - m_overbarLeftPointShift, adjustedPaintOffset.y()); FloatPoint bottomPoint(startX - gRadicalBottomPointXFront * frontWidth, adjustedPaintOffset.y() + baseHeight + gRadicalBottomPointLower); FloatPoint dipLeftPoint(startX - gRadicalDipLeftPointXFront * frontWidth, adjustedPaintOffset.y() + radicalDipLeftPointYPos); FloatPoint leftEnd(startX - frontWidth, dipLeftPoint.y() + gRadicalLeftEndYShiftEms * style().fontSize()); GraphicsContextStateSaver stateSaver(*info.context); info.context->setStrokeThickness(gRadicalLineThicknessEms * style().fontSize()); info.context->setStrokeStyle(SolidStroke); info.context->setStrokeColor(style().visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB); info.context->setLineJoin(MiterJoin); info.context->setMiterLimit(style().fontSize()); Path root; root.moveTo(FloatPoint(overbarLeftPoint.x() + overbarWidth, adjustedPaintOffset.y())); // draw top root.addLineTo(overbarLeftPoint); // draw from top left corner to bottom point of radical root.addLineTo(bottomPoint); // draw from bottom point to top of left part of radical base "dip" root.addLineTo(dipLeftPoint); // draw to end root.addLineTo(leftEnd); info.context->strokePath(root); GraphicsContextStateSaver maskStateSaver(*info.context); // Build a mask to draw the thick part of the root. Path mask; mask.moveTo(overbarLeftPoint); mask.addLineTo(bottomPoint); mask.addLineTo(dipLeftPoint); mask.addLineTo(FloatPoint(2 * dipLeftPoint.x() - leftEnd.x(), 2 * dipLeftPoint.y() - leftEnd.y())); info.context->clip(mask); // Draw the thick part of the root. info.context->setStrokeThickness(gRadicalThickLineThicknessEms * style().fontSize()); info.context->setLineCap(SquareCap); Path line; line.moveTo(bottomPoint); line.addLineTo(dipLeftPoint); info.context->strokePath(line); }
LayoutUnit RenderReplaced::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const { if (style()->logicalWidth().isSpecified() || style()->logicalWidth().isIntrinsic()) return computeReplacedLogicalWidthRespectingMinMaxWidth(computeReplacedLogicalWidthUsing(style()->logicalWidth()), shouldComputePreferred); RenderBox* contentRenderer = embeddedContentBox(); // 10.3.2 Inline, replaced elements: http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-width double intrinsicRatio = 0; FloatSize constrainedSize; computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio); if (style()->logicalWidth().isAuto()) { bool computedHeightIsAuto = hasAutoHeightOrContainingBlockWithAutoHeight(); bool hasIntrinsicWidth = constrainedSize.width() > 0; // If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'. if (computedHeightIsAuto && hasIntrinsicWidth) return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), shouldComputePreferred); bool hasIntrinsicHeight = constrainedSize.height() > 0; if (intrinsicRatio) { // If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio; // or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio; then the used value // of 'width' is: (used height) * (intrinsic ratio) if (intrinsicRatio && ((computedHeightIsAuto && !hasIntrinsicWidth && hasIntrinsicHeight) || !computedHeightIsAuto)) { LayoutUnit logicalHeight = computeReplacedLogicalHeight(); return computeReplacedLogicalWidthRespectingMinMaxWidth(roundToInt(round(logicalHeight * intrinsicRatio)), shouldComputePreferred); } // If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width, then the used value of // 'width' is undefined in CSS 2.1. However, it is suggested that, if the containing block's width does not itself depend on the replaced element's width, then // the used value of 'width' is calculated from the constraint equation used for block-level, non-replaced elements in normal flow. if (computedHeightIsAuto && !hasIntrinsicWidth && !hasIntrinsicHeight) { if (shouldComputePreferred == ComputePreferred) return 0; // The aforementioned 'constraint equation' used for block-level, non-replaced elements in normal flow: // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block LayoutUnit logicalWidth; // FIXME: This walking up the containgBlock chain to find the first one with a specified width is bonkers. // If nothing else, it requires making sure that computeReplacedLogicalWidthRespectingMinMaxWidth cannot // depend on the width of the replaced element or we infinite loop. Right now we do that in // firstContainingBlockWithLogicalWidth by checking that width/min-width/max-width are all specified. // // Firefox 27 seems to only do this if the <svg> has a viewbox. if (RenderBlock* blockWithWidth = firstContainingBlockWithLogicalWidth(this)) { logicalWidth = blockWithWidth->computeReplacedLogicalWidthRespectingMinMaxWidth(blockWithWidth->computeReplacedLogicalWidthUsing(blockWithWidth->style()->logicalWidth()), shouldComputePreferred); } else { // FIXME: If shouldComputePreferred == ComputePreferred, then we're reading this during preferred width // computation, at which point this is reading stale data from a previous layout. logicalWidth = containingBlock()->availableLogicalWidth(); } // This solves above equation for 'width' (== logicalWidth). LayoutUnit marginStart = minimumValueForLength(style()->marginStart(), logicalWidth); LayoutUnit marginEnd = minimumValueForLength(style()->marginEnd(), logicalWidth); logicalWidth = std::max<LayoutUnit>(0, logicalWidth - (marginStart + marginEnd + (width() - clientWidth()))); return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalWidth, shouldComputePreferred); } } // Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'. if (hasIntrinsicWidth) return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), shouldComputePreferred); // Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px. If 300px is too // wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead. // Note: We fall through and instead return intrinsicLogicalWidth() here - to preserve existing WebKit behavior, which might or might not be correct, or desired. // Changing this to return cDefaultWidth, will affect lots of test results. Eg. some tests assume that a blank <img> tag (which implies width/height=auto) // has no intrinsic size, which is wrong per CSS 2.1, but matches our behavior since a long time. } return computeReplacedLogicalWidthRespectingMinMaxWidth(intrinsicLogicalWidth(), shouldComputePreferred); }
void HlaConvertRprFomOrientationToQualNetOrientation( double lat, double lon, float float_psiRadians, float float_thetaRadians, float float_phiRadians, short& azimuth, short& elevation) { // Notes: ----------------------------------------------------------------- // This function converts a DIS / RPR-FOM 1.0 orientation into QualNet // azimuth and elevation angles. // // When the entity is located exactly at the north pole, this function // will return an azimuth of 0 (facing north) when the entity is pointing // toward 180 degrees longitude. // // When the entity is located exactly at the south pole, this function // will return an azimuth of 0 (facing north) when the entity is pointing // toward 0 degrees longitude. // // This function have not been optimized at all. // (e.g., the phi angle doesn't affect the results, some vector components // end up being multipled by 0, etc.) assert(lat >= -90.0 && lat <= 90.0); assert(lon >= -180.0 && lon <= 180.0); // Introduction: ---------------------------------------------------------- // There are two coordinate systems considered: // // (1) the GCC coordinate system, and // (2) the entity coordinate system. // // Both are right-handed coordinate systems. // // The GCC coordinate system has well-defined axes. // In the entity coordinate system, the x-axis points in the direction the // entity is facing (the entity orientation). // // psi, theta, and phi are the angles by which one rotates the GCC axes // so that they match in direction with the entity axes. // // Start with the GCC axes, and rotate them in the following order: // // (1) psi, a right-handed rotation about the z-axis // (2) theta, a right-handed rotation about the new y-axis // (3) phi, a right-handed rotation about the new x-axis double psiRadians = (double) float_psiRadians; double thetaRadians = (double) float_thetaRadians; double phiRadians = (double) float_phiRadians; // Convert latitude and longitude into a unit vector. // If one imagines the earth as a unit sphere, the vector will point // to the location of the entity on the surface of the sphere. double latRadians = lat * HLA_RADIANS_PER_DEGREE; double lonRadians = lon * HLA_RADIANS_PER_DEGREE; double entityLocationX = cos(lonRadians) * cos(latRadians); double entityLocationY = sin(lonRadians) * cos(latRadians); double entityLocationZ = sin(latRadians); // Discussion of basic theory: -------------------------------------------- // Start with a point b in the initial coordinate system. b is represented // as a vector. // // Rotate the axes of the initial coordinate system by angle theta to // obtain a new coordinate system. // // Representation of point b in the new coordinate system is given by: // // c = ab // // where a is a rotation matrix: // // a = [ cos(theta) sin(theta) // -sin(theta) cos(theta) ] // // and c is the same point, but in the new coordinate system. // // Note that the coordinate system changes; the point itself does not move. // Also, matrix a is for rotating the axes; the matrix is different when // rotating the vector while not changing the axes. // // Applying this discussion to three dimensions, and using psi, theta, and // phi as described previously, three rotation matrices can be created: // // Rx = // [ 1 0 0 // 0 cos(phi) sin(phi) // 0 -sin(phi) cos(phi) ] // // Ry = // [ cos(theta) 0 -sin(theta) // 0 1 0 // sin(theta) 0 cos(theta) ] // // Rz = // [ cos(psi) sin(psi) 0 // -sin(psi) cos(psi) 0 // 0 0 1 ] // // where // // c = ab // a = (Rx)(Ry)(Rz) // // b is the point as represented in the GCC coordinate system; // c is the point as represented in the entity coordinate system. // // Note that matrix multiplication is not commutative, so the order of // the factors in a is important (rotate by Rz first, so it's on the right // side). // Determine elevation angle: --------------------------------------------- // In the computation of the elevation angle below, the change is in the // opposite direction, from the entity coordinate system to the GCC system. // So, for: // // c = ab // // Vector b represents the entity orientation as expressed in the entity // coordinate system. // Vector c represents the entity orientation as expressed in the GCC // coordinate system. // // It turns out that: // // a = (Rz)'(Ry)'(Rx)' // // where Rx, Ry, and Rz are given earlier, and the ' symbol indicates the // transpose of each matrix. // // The ordering of the matrices is reversed, since one is going from the // entity coordinate system to the GCC system. The negative of psi, theta, // and phi angles are used, and the transposed matrices end up being the // correct ones. double a11 = cos(psiRadians) * cos(thetaRadians); double a12 = -sin(psiRadians) * cos(phiRadians) + cos(psiRadians) * sin(thetaRadians) * sin(phiRadians); double a13 = -sin(psiRadians) * -sin(phiRadians) + cos(psiRadians) * sin(thetaRadians) * cos(phiRadians); double a21 = sin(psiRadians) * cos(thetaRadians); double a22 = cos(psiRadians) * cos(phiRadians) + sin(psiRadians) * sin(thetaRadians) * sin(phiRadians); double a23 = cos(psiRadians) * -sin(phiRadians) + sin(psiRadians) * sin(thetaRadians) * cos(phiRadians); double a31 = -sin(thetaRadians); double a32 = cos(thetaRadians) * sin(phiRadians); double a33 = cos(thetaRadians) * cos(phiRadians); // Vector b is chosen such that it is the unit vector pointing along the // positive x-axis of the entity coordinate system. I.e., vector b points // in the same direction the entity is facing. double b1 = 1.0; double b2 = 0.0; double b3 = 0.0; // The values below are the components of vector c, which represent the // entity orientation in the GCC coordinate system. double entityOrientationX = a11 * b1 + a12 * b2 + a13 * b3; double entityOrientationY = a21 * b1 + a22 * b2 + a23 * b3; double entityOrientationZ = a31 * b1 + a32 * b2 + a33 * b3; // One now has two vectors: // // (1) an entity-position vector, and // (2) an entity-orientation vector. // // Note that the position vector is normal to the sphere at the point where // the entity is located on the sphere. // // One can determine the angle between the two vectors using dot product // formulas. The computed angle is the deflection from the normal. double dotProduct = entityLocationX * entityOrientationX + entityLocationY * entityOrientationY + entityLocationZ * entityOrientationZ; double entityLocationMagnitude = sqrt(pow(entityLocationX, 2) + pow(entityLocationY, 2) + pow(entityLocationZ, 2)); double entityOrientationMagnitude = sqrt(pow(entityOrientationX, 2) + pow(entityOrientationY, 2) + pow(entityOrientationZ, 2)); double deflectionFromNormalToSphereRadians = acos(dotProduct / (entityLocationMagnitude * entityOrientationMagnitude)); // The elevation angle is 90 degrees minus the angle for deflection from // normal. (Note that the elevation angle can range from -90 to +90 // degrees.) double elevationRadians = (HLA_PI / 2.0) - deflectionFromNormalToSphereRadians; elevation = (short) roundToInt(elevationRadians * HLA_DEGREES_PER_RADIAN); assert(elevation >= -90 && elevation <= 90); // Determine azimuth angle: ----------------------------------------------- // To determine the azimuth angle, for: // // c = ab // // b is the entity orientation as represented in the GCC coordinate system. // // c is the entity orientation as expressed in a new coordinate system. // This is a coordinate system where the yz plane is tangent to the sphere // at the point on the sphere where the entity is located. The z-axis // points towards true north; the y-axis points towards east; the x-axis // points in the direction of the normal to the sphere. // // The rotation matrix turns is then: // // a = (Ry)(Rz) // // where longitude is used for Rz and the negative of latitude is used for // Ry (since right-handed rotations of the y-axis are positive). a11 = cos(-latRadians) * cos(lonRadians); a12 = cos(-latRadians) * sin(lonRadians); a13 = -sin(-latRadians); a21 = -sin(lonRadians); a22 = cos(lonRadians); a23 = 0; a31 = sin(-latRadians) * cos(lonRadians); a32 = sin(-latRadians) * sin(lonRadians); a33 = cos(-latRadians); b1 = entityOrientationX; b2 = entityOrientationY; b3 = entityOrientationZ; // Variable unused. //double c1 = a11 * b1 + a12 * b2 + a13 * b3; double c2 = a21 * b1 + a22 * b2 + a23 * b3; double c3 = a31 * b1 + a32 * b2 + a33 * b3; // To determine azimuth, project c against the yz plane (the plane tangent // to the sphere at the entity location), creating a new vector without an // x component. // // Determine the angle between this vector and the unit vector pointing // north, using dot-product formulas. double vectorInTangentPlaneX = 0; double vectorInTangentPlaneY = c2; double vectorInTangentPlaneZ = c3; double northVectorInTangentPlaneX = 0; double northVectorInTangentPlaneY = 0; double northVectorInTangentPlaneZ = 1; dotProduct = vectorInTangentPlaneX * northVectorInTangentPlaneX + vectorInTangentPlaneY * northVectorInTangentPlaneY + vectorInTangentPlaneZ * northVectorInTangentPlaneZ; double vectorInTangentPlaneMagnitude = sqrt(pow(vectorInTangentPlaneX, 2) + pow(vectorInTangentPlaneY, 2) + pow(vectorInTangentPlaneZ, 2)); double northVectorInTangentPlaneMagnitude = sqrt(pow(northVectorInTangentPlaneX, 2) + pow(northVectorInTangentPlaneY, 2) + pow(northVectorInTangentPlaneZ, 2)); double azimuthRadians = acos(dotProduct / (vectorInTangentPlaneMagnitude * northVectorInTangentPlaneMagnitude)); // Handle azimuth values between 180 and 360 degrees. if (vectorInTangentPlaneY < 0.0) { azimuthRadians = (2.0 * HLA_PI) - azimuthRadians; } azimuth = (short) roundToInt(azimuthRadians * HLA_DEGREES_PER_RADIAN); if (azimuth == 360) { azimuth = 0; } assert(azimuth >= 0 && azimuth <= 359); }
int MouseEvent::getMouseDownY() const noexcept { return roundToInt (mouseDownPos.y); }
int MouseEvent::getDistanceFromDragStart() const noexcept { return roundToInt (mouseDownPos.getDistanceFrom (position)); }
void OldSchoolLookAndFeel::drawLinearSlider (Graphics& g, int x, int y, int w, int h, float sliderPos, float minSliderPos, float maxSliderPos, const Slider::SliderStyle style, Slider& slider) { g.fillAll (slider.findColour (Slider::backgroundColourId)); if (style == Slider::LinearBar) { g.setColour (slider.findColour (Slider::thumbColourId)); g.fillRect (x, y, (int) sliderPos - x, h); g.setColour (slider.findColour (Slider::textBoxTextColourId).withMultipliedAlpha (0.5f)); g.drawRect (x, y, (int) sliderPos - x, h); } else { g.setColour (slider.findColour (Slider::trackColourId) .withMultipliedAlpha (slider.isEnabled() ? 1.0f : 0.3f)); if (slider.isHorizontal()) { g.fillRect (x, y + roundToInt (h * 0.6f), w, roundToInt (h * 0.2f)); } else { g.fillRect (x + roundToInt (w * 0.5f - jmin (3.0f, w * 0.1f)), y, jmin (4, roundToInt (w * 0.2f)), h); } float alpha = 0.35f; if (slider.isEnabled()) alpha = slider.isMouseOverOrDragging() ? 1.0f : 0.7f; const Colour fill (slider.findColour (Slider::thumbColourId).withAlpha (alpha)); const Colour outline (Colours::black.withAlpha (slider.isEnabled() ? 0.7f : 0.35f)); if (style == Slider::TwoValueVertical || style == Slider::ThreeValueVertical) { drawTriangle (g, x + w * 0.5f + jmin (4.0f, w * 0.3f), minSliderPos, x + w * 0.5f - jmin (8.0f, w * 0.4f), minSliderPos - 7.0f, x + w * 0.5f - jmin (8.0f, w * 0.4f), minSliderPos, fill, outline); drawTriangle (g, x + w * 0.5f + jmin (4.0f, w * 0.3f), maxSliderPos, x + w * 0.5f - jmin (8.0f, w * 0.4f), maxSliderPos, x + w * 0.5f - jmin (8.0f, w * 0.4f), maxSliderPos + 7.0f, fill, outline); } else if (style == Slider::TwoValueHorizontal || style == Slider::ThreeValueHorizontal) { drawTriangle (g, minSliderPos, y + h * 0.6f - jmin (4.0f, h * 0.3f), minSliderPos - 7.0f, y + h * 0.9f , minSliderPos, y + h * 0.9f, fill, outline); drawTriangle (g, maxSliderPos, y + h * 0.6f - jmin (4.0f, h * 0.3f), maxSliderPos, y + h * 0.9f, maxSliderPos + 7.0f, y + h * 0.9f, fill, outline); } if (style == Slider::LinearHorizontal || style == Slider::ThreeValueHorizontal) { drawTriangle (g, sliderPos, y + h * 0.9f, sliderPos - 7.0f, y + h * 0.2f, sliderPos + 7.0f, y + h * 0.2f, fill, outline); } else if (style == Slider::LinearVertical || style == Slider::ThreeValueVertical) { drawTriangle (g, x + w * 0.5f - jmin (4.0f, w * 0.3f), sliderPos, x + w * 0.5f + jmin (8.0f, w * 0.4f), sliderPos - 7.0f, x + w * 0.5f + jmin (8.0f, w * 0.4f), sliderPos + 7.0f, fill, outline); } } }
LayoutUnit RootInlineBox::lineSnapAdjustment(LayoutUnit delta) const { // If our block doesn't have snapping turned on, do nothing. // FIXME: Implement bounds snapping. if (blockFlow().style().lineSnap() == LineSnapNone) return 0; // Get the current line grid and offset. LayoutState* layoutState = blockFlow().view().layoutState(); RenderBlockFlow* lineGrid = layoutState->lineGrid(); LayoutSize lineGridOffset = layoutState->lineGridOffset(); if (!lineGrid || lineGrid->style().writingMode() != blockFlow().style().writingMode()) return 0; // Get the hypothetical line box used to establish the grid. RootInlineBox* lineGridBox = lineGrid->lineGridBox(); if (!lineGridBox) return 0; LayoutUnit lineGridBlockOffset = lineGrid->isHorizontalWritingMode() ? lineGridOffset.height() : lineGridOffset.width(); LayoutUnit blockOffset = blockFlow().isHorizontalWritingMode() ? layoutState->layoutOffset().height() : layoutState->layoutOffset().width(); // Now determine our position on the grid. Our baseline needs to be adjusted to the nearest baseline multiple // as established by the line box. // FIXME: Need to handle crazy line-box-contain values that cause the root line box to not be considered. I assume // the grid should honor line-box-contain. LayoutUnit gridLineHeight = lineGridBox->lineBottomWithLeading() - lineGridBox->lineTopWithLeading(); if (!gridLineHeight) return 0; LayoutUnit lineGridFontAscent = lineGrid->style().fontMetrics().ascent(baselineType()); LayoutUnit lineGridFontHeight = lineGridBox->logicalHeight(); LayoutUnit firstTextTop = lineGridBlockOffset + lineGridBox->logicalTop(); LayoutUnit firstLineTopWithLeading = lineGridBlockOffset + lineGridBox->lineTopWithLeading(); LayoutUnit firstBaselinePosition = firstTextTop + lineGridFontAscent; LayoutUnit currentTextTop = blockOffset + logicalTop() + delta; LayoutUnit currentFontAscent = blockFlow().style().fontMetrics().ascent(baselineType()); LayoutUnit currentBaselinePosition = currentTextTop + currentFontAscent; LayoutUnit lineGridPaginationOrigin = isHorizontal() ? layoutState->lineGridPaginationOrigin().height() : layoutState->lineGridPaginationOrigin().width(); // If we're paginated, see if we're on a page after the first one. If so, the grid resets on subsequent pages. // FIXME: If the grid is an ancestor of the pagination establisher, then this is incorrect. LayoutUnit pageLogicalTop = 0; if (layoutState->isPaginated() && layoutState->pageLogicalHeight()) { pageLogicalTop = blockFlow().pageLogicalTopForOffset(lineTopWithLeading() + delta); if (pageLogicalTop > firstLineTopWithLeading) firstTextTop = pageLogicalTop + lineGridBox->logicalTop() - lineGrid->borderAndPaddingBefore() + lineGridPaginationOrigin; } if (blockFlow().style().lineSnap() == LineSnapContain) { // Compute the desired offset from the text-top of a grid line. // Look at our height (logicalHeight()). // Look at the total available height. It's going to be (textBottom - textTop) + (n-1)*(multiple with leading) // where n is number of grid lines required to enclose us. if (logicalHeight() <= lineGridFontHeight) firstTextTop += (lineGridFontHeight - logicalHeight()) / 2; else { LayoutUnit numberOfLinesWithLeading = ceilf(static_cast<float>(logicalHeight() - lineGridFontHeight) / gridLineHeight); LayoutUnit totalHeight = lineGridFontHeight + numberOfLinesWithLeading * gridLineHeight; firstTextTop += (totalHeight - logicalHeight()) / 2; } firstBaselinePosition = firstTextTop + currentFontAscent; } else firstBaselinePosition = firstTextTop + lineGridFontAscent; // If we're above the first line, just push to the first line. if (currentBaselinePosition < firstBaselinePosition) return delta + firstBaselinePosition - currentBaselinePosition; // Otherwise we're in the middle of the grid somewhere. Just push to the next line. LayoutUnit baselineOffset = currentBaselinePosition - firstBaselinePosition; LayoutUnit remainder = roundToInt(baselineOffset) % roundToInt(gridLineHeight); LayoutUnit result = delta; if (remainder) result += gridLineHeight - remainder; // If we aren't paginated we can return the result. if (!layoutState->isPaginated() || !layoutState->pageLogicalHeight() || result == delta) return result; // We may end up shifted to a new page. We need to do a re-snap when that happens. LayoutUnit newPageLogicalTop = blockFlow().pageLogicalTopForOffset(lineBottomWithLeading() + result); if (newPageLogicalTop == pageLogicalTop) return result; // Put ourselves at the top of the next page to force a snap onto the new grid established by that page. return lineSnapAdjustment(newPageLogicalTop - (blockOffset + lineTopWithLeading())); }
void updateMarker() { marker.setBounds (roundToInt ((getWidth() - edge * 2) * s), roundToInt ((getHeight() - edge * 2) * (1.0f - v)), edge * 2, edge * 2); }
void DropShadower::updateShadows() { if (reentrant || owner == nullptr) return; ComponentPeer* const peer = owner->getPeer(); const bool isOwnerVisible = owner->isVisible() && (peer == nullptr || ! peer->isMinimised()); const bool createShadowWindows = shadowWindows.size() == 0 && owner->getWidth() > 0 && owner->getHeight() > 0 && isOwnerVisible && (Desktop::canUseSemiTransparentWindows() || owner->getParentComponent() != nullptr); { const ScopedValueSetter<bool> setter (reentrant, true, false); const int shadowEdge = jmax (xOffset, yOffset) + (int) blurRadius; if (createShadowWindows) { // keep a cached version of the image to save doing the gaussian too often String imageId; imageId << shadowEdge << ',' << xOffset << ',' << yOffset << ',' << alpha; const int hash = imageId.hashCode(); Image bigIm (ImageCache::getFromHashCode (hash)); if (bigIm.isNull()) { bigIm = Image (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true); Graphics bigG (bigIm); bigG.setColour (Colours::black.withAlpha (alpha)); bigG.fillRect (shadowEdge + xOffset, shadowEdge + yOffset, bigIm.getWidth() - (shadowEdge * 2), bigIm.getHeight() - (shadowEdge * 2)); ImageConvolutionKernel blurKernel (roundToInt (blurRadius * 2.0f)); blurKernel.createGaussianBlur (blurRadius); blurKernel.applyToImage (bigIm, bigIm, Rectangle<int> (xOffset, yOffset, bigIm.getWidth(), bigIm.getHeight())); ImageCache::addImageToCache (bigIm, hash); } const int iw = bigIm.getWidth(); const int ih = bigIm.getHeight(); const int shadowEdge2 = shadowEdge * 2; setShadowImage (bigIm, 0, shadowEdge, shadowEdge2, 0, 0); setShadowImage (bigIm, 1, shadowEdge, shadowEdge2, 0, ih - shadowEdge2); setShadowImage (bigIm, 2, shadowEdge, shadowEdge, 0, shadowEdge2); setShadowImage (bigIm, 3, shadowEdge, shadowEdge2, iw - shadowEdge, 0); setShadowImage (bigIm, 4, shadowEdge, shadowEdge2, iw - shadowEdge, ih - shadowEdge2); setShadowImage (bigIm, 5, shadowEdge, shadowEdge, iw - shadowEdge, shadowEdge2); setShadowImage (bigIm, 6, shadowEdge, shadowEdge, shadowEdge, 0); setShadowImage (bigIm, 7, shadowEdge, shadowEdge, iw - shadowEdge2, 0); setShadowImage (bigIm, 8, shadowEdge, shadowEdge, shadowEdge2, 0); setShadowImage (bigIm, 9, shadowEdge, shadowEdge, shadowEdge, ih - shadowEdge); setShadowImage (bigIm, 10, shadowEdge, shadowEdge, iw - shadowEdge2, ih - shadowEdge); setShadowImage (bigIm, 11, shadowEdge, shadowEdge, shadowEdge2, ih - shadowEdge); for (int i = 0; i < 4; ++i) shadowWindows.add (new ShadowWindow (*owner, i, shadowImageSections)); } if (shadowWindows.size() >= 4) { const int x = owner->getX(); const int y = owner->getY() - shadowEdge; const int w = owner->getWidth(); const int h = owner->getHeight() + shadowEdge + shadowEdge; for (int i = shadowWindows.size(); --i >= 0;) { // there seem to be rare situations where the dropshadower may be deleted by // callbacks during this loop, so use a weak ref to watch out for this.. WeakReference<Component> sw (shadowWindows[i]); if (sw != nullptr) sw->setAlwaysOnTop (owner->isAlwaysOnTop()); if (sw != nullptr) sw->setVisible (isOwnerVisible); if (sw != nullptr) { switch (i) { case 0: sw->setBounds (x - shadowEdge, y, shadowEdge, h); break; case 1: sw->setBounds (x + w, y, shadowEdge, h); break; case 2: sw->setBounds (x, y, w, shadowEdge); break; case 3: sw->setBounds (x, owner->getBottom(), w, shadowEdge); break; default: break; } } if (sw == nullptr) return; } } } if (createShadowWindows) bringShadowWindowsToFront(); }
void BackgroundImageGeometry::calculate( const LayoutBoxModelObject& obj, const LayoutBoxModelObject* paintContainer, const GlobalPaintFlags globalPaintFlags, const FillLayer& fillLayer, const LayoutRect& paintRect) { LayoutUnit left; LayoutUnit top; LayoutSize positioningAreaSize; bool isLayoutView = obj.isLayoutView(); const LayoutBox* rootBox = nullptr; if (isLayoutView) { // It is only possible reach here when root element has a box. Element* documentElement = obj.document().documentElement(); DCHECK(documentElement); DCHECK(documentElement->layoutObject()); DCHECK(documentElement->layoutObject()->isBox()); rootBox = toLayoutBox(documentElement->layoutObject()); } const LayoutBoxModelObject& positioningBox = isLayoutView ? static_cast<const LayoutBoxModelObject&>(*rootBox) : obj; // Determine the background positioning area and set destRect to the // background painting area. destRect will be adjusted later if the // background is non-repeating. // FIXME: transforms spec says that fixed backgrounds behave like scroll // inside transforms. bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { // As a side effect of an optimization to blit on scroll, we do not honor // the CSS property "background-attachment: fixed" because it may result in // rendering artifacts. Note, these artifacts only appear if we are blitting // on scroll of a page that has fixed background images. fixedAttachment = false; } if (!fixedAttachment) { setDestRect(paintRect); LayoutUnit right; LayoutUnit bottom; // Scroll and Local. if (fillLayer.origin() != BorderFillBox) { left = LayoutUnit(positioningBox.borderLeft()); right = LayoutUnit(positioningBox.borderRight()); top = LayoutUnit(positioningBox.borderTop()); bottom = LayoutUnit(positioningBox.borderBottom()); if (fillLayer.origin() == ContentFillBox) { left += positioningBox.paddingLeft(); right += positioningBox.paddingRight(); top += positioningBox.paddingTop(); bottom += positioningBox.paddingBottom(); } } if (isLayoutView) { // The background of the box generated by the root element covers the // entire canvas and will be painted by the view object, but the we should // still use the root element box for positioning. positioningAreaSize = rootBox->size() - LayoutSize(left + right, top + bottom), rootBox->location(); // The input paint rect is specified in root element local coordinate // (i.e. a transform is applied on the context for painting), and is // expanded to cover the whole canvas. Since left/top is relative to the // paint rect, we need to offset them back. left -= paintRect.x(); top -= paintRect.y(); } else { positioningAreaSize = paintRect.size() - LayoutSize(left + right, top + bottom); } } else { setHasNonLocalGeometry(); LayoutRect viewportRect = obj.viewRect(); if (fixedBackgroundPaintsInLocalCoordinates(obj, globalPaintFlags)) { viewportRect.setLocation(LayoutPoint()); } else { if (FrameView* frameView = obj.view()->frameView()) viewportRect.setLocation(IntPoint(frameView->scrollOffsetInt())); // Compensate the translations created by ScrollRecorders. // TODO(trchen): Fix this for SP phase 2. crbug.com/529963. viewportRect.moveBy( accumulatedScrollOffsetForFixedBackground(obj, paintContainer)); } if (paintContainer) viewportRect.moveBy( LayoutPoint(-paintContainer->localToAbsolute(FloatPoint()))); setDestRect(viewportRect); positioningAreaSize = destRect().size(); } LayoutSize fillTileSize( calculateFillTileSize(positioningBox, fillLayer, positioningAreaSize)); // It's necessary to apply the heuristic here prior to any further // calculations to avoid incorrectly using sub-pixel values that won't be // present in the painted tile. setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); EFillRepeat backgroundRepeatX = fillLayer.repeatX(); EFillRepeat backgroundRepeatY = fillLayer.repeatY(); LayoutUnit unsnappedAvailableWidth = positioningAreaSize.width() - fillTileSize.width(); LayoutUnit unsnappedAvailableHeight = positioningAreaSize.height() - fillTileSize.height(); positioningAreaSize = LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()), snapSizeToPixel(positioningAreaSize.height(), m_destRect.y())); LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width(); LayoutUnit availableHeight = positioningAreaSize.height() - tileSize().height(); LayoutUnit computedXPosition = roundedMinimumValueForLength(fillLayer.xPosition(), availableWidth); if (backgroundRepeatX == RoundFill && positioningAreaSize.width() > LayoutUnit() && fillTileSize.width() > LayoutUnit()) { int nrTiles = std::max( 1, roundToInt(positioningAreaSize.width() / fillTileSize.width())); LayoutUnit roundedWidth = positioningAreaSize.width() / nrTiles; // Maintain aspect ratio if background-size: auto is set if (fillLayer.size().size.height().isAuto() && backgroundRepeatY != RoundFill) { fillTileSize.setHeight(fillTileSize.height() * roundedWidth / fillTileSize.width()); } fillTileSize.setWidth(roundedWidth); setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); setPhaseX(tileSize().width() ? LayoutUnit(roundf( tileSize().width() - fmodf((computedXPosition + left), tileSize().width()))) : LayoutUnit()); setSpaceSize(LayoutSize()); } LayoutUnit computedYPosition = roundedMinimumValueForLength(fillLayer.yPosition(), availableHeight); if (backgroundRepeatY == RoundFill && positioningAreaSize.height() > LayoutUnit() && fillTileSize.height() > LayoutUnit()) { int nrTiles = std::max( 1, roundToInt(positioningAreaSize.height() / fillTileSize.height())); LayoutUnit roundedHeight = positioningAreaSize.height() / nrTiles; // Maintain aspect ratio if background-size: auto is set if (fillLayer.size().size.width().isAuto() && backgroundRepeatX != RoundFill) { fillTileSize.setWidth(fillTileSize.width() * roundedHeight / fillTileSize.height()); } fillTileSize.setHeight(roundedHeight); setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); setPhaseY(tileSize().height() ? LayoutUnit(roundf( tileSize().height() - fmodf((computedYPosition + top), tileSize().height()))) : LayoutUnit()); setSpaceSize(LayoutSize()); } if (backgroundRepeatX == RepeatFill) { setRepeatX(fillLayer, fillTileSize.width(), availableWidth, unsnappedAvailableWidth, left); } else if (backgroundRepeatX == SpaceFill && tileSize().width() > LayoutUnit()) { LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width(), tileSize().width()); if (space >= LayoutUnit()) setSpaceX(space, availableWidth, left); else backgroundRepeatX = NoRepeatFill; } if (backgroundRepeatX == NoRepeatFill) { LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge ? availableWidth - computedXPosition : computedXPosition; setNoRepeatX(left + xOffset); } if (backgroundRepeatY == RepeatFill) { setRepeatY(fillLayer, fillTileSize.height(), availableHeight, unsnappedAvailableHeight, top); } else if (backgroundRepeatY == SpaceFill && tileSize().height() > LayoutUnit()) { LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height(), tileSize().height()); if (space >= LayoutUnit()) setSpaceY(space, availableHeight, top); else backgroundRepeatY = NoRepeatFill; } if (backgroundRepeatY == NoRepeatFill) { LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge ? availableHeight - computedYPosition : computedYPosition; setNoRepeatY(top + yOffset); } if (fixedAttachment) useFixedAttachment(paintRect.location()); // Clip the final output rect to the paint rect m_destRect.intersect(paintRect); // Snap as-yet unsnapped values. setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect))); }
void DragAndDropContainer::startDragging (const var& sourceDescription, Component* sourceComponent, const Image& dragImage_, const bool allowDraggingToExternalWindows, const Point<int>* imageOffsetFromMouse) { Image dragImage (dragImage_); if (dragImageComponent == nullptr) { MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource (0); if (draggingSource == nullptr || ! draggingSource->isDragging()) { jassertfalse; // You must call startDragging() from within a mouseDown or mouseDrag callback! return; } const Point<int> lastMouseDown (Desktop::getLastMouseDownPosition()); Point<int> imageOffset; if (dragImage.isNull()) { dragImage = sourceComponent->createComponentSnapshot (sourceComponent->getLocalBounds()) .convertedToFormat (Image::ARGB); dragImage.multiplyAllAlphas (0.6f); const int lo = 150; const int hi = 400; Point<int> relPos (sourceComponent->getLocalPoint (nullptr, lastMouseDown)); Point<int> clipped (dragImage.getBounds().getConstrainedPoint (relPos)); Random random; for (int y = dragImage.getHeight(); --y >= 0;) { const double dy = (y - clipped.getY()) * (y - clipped.getY()); for (int x = dragImage.getWidth(); --x >= 0;) { const int dx = x - clipped.getX(); const int distance = roundToInt (std::sqrt (dx * dx + dy)); if (distance > lo) { const float alpha = (distance > hi) ? 0 : (hi - distance) / (float) (hi - lo) + random.nextFloat() * 0.008f; dragImage.multiplyAlphaAt (x, y, alpha); } } } imageOffset = clipped; } else { if (imageOffsetFromMouse == nullptr) imageOffset = dragImage.getBounds().getCentre(); else imageOffset = dragImage.getBounds().getConstrainedPoint (-*imageOffsetFromMouse); } dragImageComponent = new DragImageComponent (dragImage, sourceDescription, sourceComponent, draggingSource->getComponentUnderMouse(), *this, imageOffset); currentDragDesc = sourceDescription; if (allowDraggingToExternalWindows) { if (! Desktop::canUseSemiTransparentWindows()) dragImageComponent->setOpaque (true); dragImageComponent->addToDesktop (ComponentPeer::windowIgnoresMouseClicks | ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses); } else { Component* const thisComp = dynamic_cast <Component*> (this); if (thisComp == nullptr) { jassertfalse; // Your DragAndDropContainer needs to be a Component! return; } thisComp->addChildComponent (dragImageComponent); } static_cast <DragImageComponent*> (dragImageComponent.get())->updateLocation (false, lastMouseDown); dragImageComponent->setVisible (true); #if JUCE_WINDOWS // Under heavy load, the layered window's paint callback can often be lost by the OS, // so forcing a repaint at least once makes sure that the window becomes visible.. ComponentPeer* const peer = dragImageComponent->getPeer(); if (peer != nullptr) peer->performAnyPendingRepaintsNow(); #endif } }
int MouseRelatedEvent::offsetY() { if (!m_hasCachedRelativePosition) computeRelativePosition(); return roundToInt(m_offsetLocation.y()); }
int64 AudioFormatReader::searchForLevel (int64 startSample, int64 numSamplesToSearch, const double magnitudeRangeMinimum, const double magnitudeRangeMaximum, const int minimumConsecutiveSamples) { if (numSamplesToSearch == 0) return -1; const int bufferSize = 4096; HeapBlock<int> tempSpace (bufferSize * 2 + 64); int* tempBuffer[3]; tempBuffer[0] = tempSpace.getData(); tempBuffer[1] = tempSpace.getData() + bufferSize; tempBuffer[2] = 0; int consecutive = 0; int64 firstMatchPos = -1; jassert (magnitudeRangeMaximum > magnitudeRangeMinimum); const double doubleMin = jlimit (0.0, (double) std::numeric_limits<int>::max(), magnitudeRangeMinimum * std::numeric_limits<int>::max()); const double doubleMax = jlimit (doubleMin, (double) std::numeric_limits<int>::max(), magnitudeRangeMaximum * std::numeric_limits<int>::max()); const int intMagnitudeRangeMinimum = roundToInt (doubleMin); const int intMagnitudeRangeMaximum = roundToInt (doubleMax); while (numSamplesToSearch != 0) { const int numThisTime = (int) jmin (abs64 (numSamplesToSearch), (int64) bufferSize); int64 bufferStart = startSample; if (numSamplesToSearch < 0) bufferStart -= numThisTime; if (bufferStart >= (int) lengthInSamples) break; read (tempBuffer, 2, bufferStart, numThisTime, false); int num = numThisTime; while (--num >= 0) { if (numSamplesToSearch < 0) --startSample; bool matches = false; const int index = (int) (startSample - bufferStart); if (usesFloatingPointData) { const float sample1 = std::abs (((float*) tempBuffer[0]) [index]); if (sample1 >= magnitudeRangeMinimum && sample1 <= magnitudeRangeMaximum) { matches = true; } else if (numChannels > 1) { const float sample2 = std::abs (((float*) tempBuffer[1]) [index]); matches = (sample2 >= magnitudeRangeMinimum && sample2 <= magnitudeRangeMaximum); } } else { const int sample1 = abs (tempBuffer[0] [index]); if (sample1 >= intMagnitudeRangeMinimum && sample1 <= intMagnitudeRangeMaximum) { matches = true; } else if (numChannels > 1) { const int sample2 = abs (tempBuffer[1][index]); matches = (sample2 >= intMagnitudeRangeMinimum && sample2 <= intMagnitudeRangeMaximum); } } if (matches) { if (firstMatchPos < 0) firstMatchPos = startSample; if (++consecutive >= minimumConsecutiveSamples) { if (firstMatchPos < 0 || firstMatchPos >= lengthInSamples) return -1; return firstMatchPos; } } else { consecutive = 0; firstMatchPos = -1; } if (numSamplesToSearch > 0) ++startSample; } if (numSamplesToSearch > 0) numSamplesToSearch -= numThisTime; else numSamplesToSearch += numThisTime; } return -1; }
LayoutUnit RenderReplaced::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const { if (style()->logicalWidth().isSpecified() || style()->logicalWidth().isIntrinsic()) return computeReplacedLogicalWidthRespectingMinMaxWidth(computeReplacedLogicalWidthUsing(MainOrPreferredSize, style()->logicalWidth()), shouldComputePreferred); RenderBox* contentRenderer = embeddedContentBox(); // 10.3.2 Inline, replaced elements: http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-width bool isPercentageIntrinsicSize = false; double intrinsicRatio = 0; FloatSize constrainedSize; computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio, isPercentageIntrinsicSize); if (style()->logicalWidth().isAuto()) { bool heightIsAuto = style()->logicalHeight().isAuto(); bool hasIntrinsicWidth = !isPercentageIntrinsicSize && constrainedSize.width() > 0; // If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'. if (heightIsAuto && hasIntrinsicWidth) return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), shouldComputePreferred); bool hasIntrinsicHeight = !isPercentageIntrinsicSize && constrainedSize.height() > 0; if (intrinsicRatio || isPercentageIntrinsicSize) { // If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio; // or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio; then the used value // of 'width' is: (used height) * (intrinsic ratio) if (intrinsicRatio && ((heightIsAuto && !hasIntrinsicWidth && hasIntrinsicHeight) || !heightIsAuto)) { LayoutUnit logicalHeight = computeReplacedLogicalHeight(); return computeReplacedLogicalWidthRespectingMinMaxWidth(roundToInt(round(logicalHeight * intrinsicRatio)), shouldComputePreferred); } // If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width, then the used value of // 'width' is undefined in CSS 2.1. However, it is suggested that, if the containing block's width does not itself depend on the replaced element's width, then // the used value of 'width' is calculated from the constraint equation used for block-level, non-replaced elements in normal flow. if (heightIsAuto && !hasIntrinsicWidth && !hasIntrinsicHeight) { // The aforementioned 'constraint equation' used for block-level, non-replaced elements in normal flow: // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block LayoutUnit logicalWidth; if (RenderBlock* blockWithWidth = firstContainingBlockWithLogicalWidth(this)) logicalWidth = blockWithWidth->computeReplacedLogicalWidthRespectingMinMaxWidth(blockWithWidth->computeReplacedLogicalWidthUsing(MainOrPreferredSize, blockWithWidth->style()->logicalWidth()), shouldComputePreferred); else logicalWidth = containingBlock()->availableLogicalWidth(); // This solves above equation for 'width' (== logicalWidth). LayoutUnit marginStart = minimumValueForLength(style()->marginStart(), logicalWidth); LayoutUnit marginEnd = minimumValueForLength(style()->marginEnd(), logicalWidth); logicalWidth = max<LayoutUnit>(0, logicalWidth - (marginStart + marginEnd + (width() - clientWidth()))); if (isPercentageIntrinsicSize) logicalWidth = logicalWidth * constrainedSize.width() / 100; return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalWidth, shouldComputePreferred); } } // Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'. if (hasIntrinsicWidth) return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), shouldComputePreferred); // Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px. If 300px is too // wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead. // Note: We fall through and instead return intrinsicLogicalWidth() here - to preserve existing WebKit behavior, which might or might not be correct, or desired. // Changing this to return cDefaultWidth, will affect lots of test results. Eg. some tests assume that a blank <img> tag (which implies width/height=auto) // has no intrinsic size, which is wrong per CSS 2.1, but matches our behavior since a long time. } return computeReplacedLogicalWidthRespectingMinMaxWidth(intrinsicLogicalWidth(), shouldComputePreferred); }
void refillCache (const int numSamples, double startTime, const double endTime, const double sampleRate, const int numChannels, const int samplesPerThumbSample, LevelDataSource* levelData, const OwnedArray<ThumbData>& channels) { const double timePerPixel = (endTime - startTime) / numSamples; if (numSamples <= 0 || timePerPixel <= 0.0 || sampleRate <= 0) { invalidate(); return; } if (numSamples == numSamplesCached && numChannelsCached == numChannels && startTime == cachedStart && timePerPixel == cachedTimePerPixel && ! cacheNeedsRefilling) { return; } numSamplesCached = numSamples; numChannelsCached = numChannels; cachedStart = startTime; cachedTimePerPixel = timePerPixel; cacheNeedsRefilling = false; ensureSize (numSamples); if (timePerPixel * sampleRate <= samplesPerThumbSample && levelData != nullptr) { int sample = roundToInt (startTime * sampleRate); Array<float> levels; int i; for (i = 0; i < numSamples; ++i) { const int nextSample = roundToInt ((startTime + timePerPixel) * sampleRate); if (sample >= 0) { if (sample >= levelData->lengthInSamples) break; levelData->getLevels (sample, jmax (1, nextSample - sample), levels); const int numChans = jmin (levels.size() / 2, numChannelsCached); for (int chan = 0; chan < numChans; ++chan) getData (chan, i)->setFloat (levels.getUnchecked (chan * 2), levels.getUnchecked (chan * 2 + 1)); } startTime += timePerPixel; sample = nextSample; } numSamplesCached = i; } else { jassert (channels.size() == numChannelsCached); for (int channelNum = 0; channelNum < numChannelsCached; ++channelNum) { ThumbData* channelData = channels.getUnchecked (channelNum); MinMaxValue* cacheData = getData (channelNum, 0); const double timeToThumbSampleFactor = sampleRate / (double) samplesPerThumbSample; startTime = cachedStart; int sample = roundToInt (startTime * timeToThumbSampleFactor); for (int i = numSamples; --i >= 0;) { const int nextSample = roundToInt ((startTime + timePerPixel) * timeToThumbSampleFactor); channelData->getMinMax (sample, nextSample, *cacheData); ++cacheData; startTime += timePerPixel; sample = nextSample; } } } }
void TimelineCursor::setPlayerPosition(int mousePosX) { const int firstPixel = roundToInt(getWidth() * _offsetRatio); double position = _xScale * (mousePosX - firstPixel); _transporSource.setPosition(position); }
void Viewport::setViewPositionProportionately (const double x, const double y) { if (contentComp != nullptr) setViewPosition (jmax (0, roundToInt (x * (contentComp->getWidth() - getWidth()))), jmax (0, roundToInt (y * (contentComp->getHeight() - getHeight())))); }