Ejemplo n.º 1
0
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));
    }
}
Ejemplo n.º 5
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());
}
Ejemplo n.º 7
0
 int getLatency (AudioSessionPropertyID propID)
 {
     Float32 latency = 0;
     getSessionProperty (propID, latency);
     return roundToInt (latency * getCurrentSampleRate());
 }
Ejemplo n.º 8
0
 void resized()
 {
     marker.setBounds (0, roundToInt ((getHeight() - edge * 2) * h),
                       getWidth(), edge * 2);
 }
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
int MouseEvent::getMouseDownY() const noexcept                  { return roundToInt (mouseDownPos.y); }
Ejemplo n.º 13
0
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);
        }
    }
}
Ejemplo n.º 15
0
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()));
}
Ejemplo n.º 16
0
 void updateMarker()
 {
     marker.setBounds (roundToInt ((getWidth() - edge * 2) * s),
                       roundToInt ((getHeight() - edge * 2) * (1.0f - v)),
                       edge * 2, edge * 2);
 }
Ejemplo n.º 17
0
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();
}
Ejemplo n.º 18
0
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
    }
}
Ejemplo n.º 20
0
int MouseRelatedEvent::offsetY()
{
    if (!m_hasCachedRelativePosition)
        computeRelativePosition();
    return roundToInt(m_offsetLocation.y());
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
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);
}
Ejemplo n.º 23
0
    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;
                }
            }
        }
    }
Ejemplo n.º 24
0
void TimelineCursor::setPlayerPosition(int mousePosX)
{
    const int firstPixel = roundToInt(getWidth() * _offsetRatio);
    double position = _xScale * (mousePosX - firstPixel);
    _transporSource.setPosition(position);
}
Ejemplo n.º 25
0
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()))));
}