<commit_before>#include "FboQuickWindow.h"

#include <QOpenGLContext>
#include <QOffscreenSurface>
#include <QOpenGLFramebufferObject>
#include <QQuickRenderControl>

#include <QTimer>

FboQuickWindow::FboQuickWindow( QOpenGLContext* context /*= 0*/ )
    : QQuickWindow( &m_renderControl ),
      m_context( 0 ), m_offscreenSurface( 0 ), m_fbo( 0 ),
      m_needPolishAndSync( true )
{
    connect( this, &QQuickWindow::sceneGraphInitialized,
             this, &FboQuickWindow::sceneGraphInitialized );
    connect( this, &QQuickWindow::sceneGraphInvalidated,
             this, &FboQuickWindow::sceneGraphInitialized );

    connect( &m_renderControl, &QQuickRenderControl::renderRequested,
             this, &FboQuickWindow::renderRequested );
    connect( &m_renderControl, &QQuickRenderControl::sceneChanged,
             this, &FboQuickWindow::sceneChanged );

    m_renderTimer.setSingleShot( true );
    m_renderTimer.setInterval( 5 );
    connect( &m_renderTimer, &QTimer::timeout,
             this, &FboQuickWindow::render );

    if( context )
        init( context );
}

FboQuickWindow::~FboQuickWindow()
{
    disconnect( this, &QQuickWindow::sceneGraphInitialized,
                this, &FboQuickWindow::sceneGraphInitialized );
    disconnect( this, &QQuickWindow::sceneGraphInvalidated,
                this, &FboQuickWindow::sceneGraphInitialized );

    disconnect( &m_renderControl, &QQuickRenderControl::renderRequested,
                this, &FboQuickWindow::renderRequested );
    disconnect( &m_renderControl, &QQuickRenderControl::sceneChanged,
                this, &FboQuickWindow::sceneChanged );

    if( m_context && m_offscreenSurface &&
        m_context->makeCurrent( m_offscreenSurface ) )
    {
        m_renderControl.invalidate();
    }

    destroyFbo();

    delete m_offscreenSurface;
}

void FboQuickWindow::init( QOpenGLContext* extContext )
{
    Q_ASSERT( extContext );
    Q_ASSERT( !m_context && !m_offscreenSurface && !m_fbo );

    m_context = extContext;
    m_context->setParent( this );

    m_offscreenSurface = new QOffscreenSurface();
    m_offscreenSurface->setFormat( m_context->format() );
    m_offscreenSurface->create();

    m_context->makeCurrent( m_offscreenSurface );
    m_renderControl.initialize( m_context );
    m_context->doneCurrent();
}

void FboQuickWindow::createFbo()
{
    Q_ASSERT( !m_fbo );

    QSize size = this->size();
    if( m_context && size.width() && size.height() ) {
        m_fbo =
            new QOpenGLFramebufferObject( size,
                                          QOpenGLFramebufferObject::CombinedDepthStencil );
        setRenderTarget( m_fbo );
    }
}

void FboQuickWindow::destroyFbo()
{
    delete m_fbo;
    m_fbo = 0;
}

void FboQuickWindow::sceneGraphInitialized()
{
    createFbo();
}

void FboQuickWindow::sceneGraphInvalidated()
{
    destroyFbo();
}

void FboQuickWindow::renderRequested()
{
    if( !m_renderTimer.isActive() )
        m_renderTimer.start();
}

void FboQuickWindow::sceneChanged()
{
    m_needPolishAndSync = true;
    if( !m_renderTimer.isActive() )
        m_renderTimer.start();
}

void FboQuickWindow::render()
{
    if( m_context->makeCurrent( m_offscreenSurface ) ) {
        if( m_needPolishAndSync ) {
            m_needPolishAndSync = false;
            //FIXME! better do it in separate thread
            m_renderControl.polishItems();
            m_renderControl.sync();
        }
        m_renderControl.render();

        resetOpenGLState();

        m_context->doneCurrent();
    }
}

void FboQuickWindow::resizeEvent( QResizeEvent* )
{
    if( m_context && m_context->makeCurrent( m_offscreenSurface ) ) {
        destroyFbo();
        createFbo();
        m_context->doneCurrent();
    }
}

void FboQuickWindow::resize( const QSize& newSize )
{
    //have to emulate resize event since Qt don't generate some events on hidden window
    QResizeEvent event( size(), newSize );
    QQuickWindow::resize( newSize );
    resizeEvent( &event );
}

void FboQuickWindow::resize( int w, int h )
{
    resize( QSize( w, h ) );
}
<commit_msg>use setGeometry instead of resize<commit_after>#include "FboQuickWindow.h"

#include <QOpenGLContext>
#include <QOffscreenSurface>
#include <QOpenGLFramebufferObject>
#include <QQuickRenderControl>

#include <QTimer>

FboQuickWindow::FboQuickWindow( QOpenGLContext* context /*= 0*/ )
    : QQuickWindow( &m_renderControl ),
      m_context( 0 ), m_offscreenSurface( 0 ), m_fbo( 0 ),
      m_needPolishAndSync( true )
{
    connect( this, &QQuickWindow::sceneGraphInitialized,
             this, &FboQuickWindow::sceneGraphInitialized );
    connect( this, &QQuickWindow::sceneGraphInvalidated,
             this, &FboQuickWindow::sceneGraphInitialized );

    connect( &m_renderControl, &QQuickRenderControl::renderRequested,
             this, &FboQuickWindow::renderRequested );
    connect( &m_renderControl, &QQuickRenderControl::sceneChanged,
             this, &FboQuickWindow::sceneChanged );

    m_renderTimer.setSingleShot( true );
    m_renderTimer.setInterval( 5 );
    connect( &m_renderTimer, &QTimer::timeout,
             this, &FboQuickWindow::render );

    if( context )
        init( context );
}

FboQuickWindow::~FboQuickWindow()
{
    disconnect( this, &QQuickWindow::sceneGraphInitialized,
                this, &FboQuickWindow::sceneGraphInitialized );
    disconnect( this, &QQuickWindow::sceneGraphInvalidated,
                this, &FboQuickWindow::sceneGraphInitialized );

    disconnect( &m_renderControl, &QQuickRenderControl::renderRequested,
                this, &FboQuickWindow::renderRequested );
    disconnect( &m_renderControl, &QQuickRenderControl::sceneChanged,
                this, &FboQuickWindow::sceneChanged );

    if( m_context && m_offscreenSurface &&
        m_context->makeCurrent( m_offscreenSurface ) )
    {
        m_renderControl.invalidate();
    }

    destroyFbo();

    delete m_offscreenSurface;
}

void FboQuickWindow::init( QOpenGLContext* extContext )
{
    Q_ASSERT( extContext );
    Q_ASSERT( !m_context && !m_offscreenSurface && !m_fbo );

    m_context = extContext;
    m_context->setParent( this );

    m_offscreenSurface = new QOffscreenSurface();
    m_offscreenSurface->setFormat( m_context->format() );
    m_offscreenSurface->create();

    m_context->makeCurrent( m_offscreenSurface );
    m_renderControl.initialize( m_context );
    m_context->doneCurrent();
}

void FboQuickWindow::createFbo()
{
    Q_ASSERT( !m_fbo );

    QSize size = this->size();
    if( m_context && size.width() && size.height() ) {
        m_fbo =
            new QOpenGLFramebufferObject( size,
                                          QOpenGLFramebufferObject::CombinedDepthStencil );
        setRenderTarget( m_fbo );
    }
}

void FboQuickWindow::destroyFbo()
{
    delete m_fbo;
    m_fbo = 0;
}

void FboQuickWindow::sceneGraphInitialized()
{
    createFbo();
}

void FboQuickWindow::sceneGraphInvalidated()
{
    destroyFbo();
}

void FboQuickWindow::renderRequested()
{
    if( !m_renderTimer.isActive() )
        m_renderTimer.start();
}

void FboQuickWindow::sceneChanged()
{
    m_needPolishAndSync = true;
    if( !m_renderTimer.isActive() )
        m_renderTimer.start();
}

void FboQuickWindow::render()
{
    if( m_context->makeCurrent( m_offscreenSurface ) ) {
        if( m_needPolishAndSync ) {
            m_needPolishAndSync = false;
            //FIXME! better do it in separate thread
            m_renderControl.polishItems();
            m_renderControl.sync();
        }
        m_renderControl.render();

        resetOpenGLState();

        m_context->doneCurrent();
    }
}

void FboQuickWindow::resizeEvent( QResizeEvent* )
{
    if( m_context && m_context->makeCurrent( m_offscreenSurface ) ) {
        destroyFbo();
        createFbo();
        m_context->doneCurrent();
    }
}

void FboQuickWindow::resize( const QSize& newSize )
{
    //have to emulate resize event since Qt don't generate some events on hidden window
    QResizeEvent event( size(), newSize );
    setGeometry( 0, 0, newSize.width(), newSize.height() );
    resizeEvent( &event );
}

void FboQuickWindow::resize( int w, int h )
{
    resize( QSize( w, h ) );
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/registry.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

const wchar_t kRootKey[] = L"Base_Registry_Unittest";

class RegistryTest : public testing::Test {
 public:
  RegistryTest() {}

 protected:
  virtual void SetUp() {
    // Create a temporary key.
    RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
    key.DeleteKey(kRootKey);
    ASSERT_FALSE(key.Open(HKEY_CURRENT_USER, kRootKey, KEY_READ));
    ASSERT_TRUE(key.Create(HKEY_CURRENT_USER, kRootKey, KEY_READ));
  }

  virtual void TearDown() {
    // Clean up the temporary key.
    RegKey key(HKEY_CURRENT_USER, L"", KEY_SET_VALUE);
    ASSERT_TRUE(key.DeleteKey(kRootKey));
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(RegistryTest);
};

TEST_F(RegistryTest, ValueTest) {
  RegKey key;

  std::wstring foo_key(kRootKey);
  foo_key += L"\\Foo";
  ASSERT_TRUE(key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ));

  {
    ASSERT_TRUE(key.Open(HKEY_CURRENT_USER, foo_key.c_str(),
                         KEY_READ | KEY_SET_VALUE));

    const wchar_t* kName = L"Bar";
    const wchar_t* kValue = L"bar";
    EXPECT_TRUE(key.WriteValue(kName, kValue));
    EXPECT_TRUE(key.ValueExists(kName));
    std::wstring out_value;
    EXPECT_TRUE(key.ReadValue(kName, &out_value));
    EXPECT_NE(out_value, L"");
    EXPECT_STREQ(out_value.c_str(), kValue);
    EXPECT_EQ(1U, key.ValueCount());
    EXPECT_TRUE(key.DeleteValue(kName));
  }
}

}  // namespace
<commit_msg>Fix perms on another of tfarina's commits.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/registry.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

const wchar_t kRootKey[] = L"Base_Registry_Unittest";

class RegistryTest : public testing::Test {
 public:
  RegistryTest() {}

 protected:
  virtual void SetUp() {
    // Create a temporary key.
    RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
    key.DeleteKey(kRootKey);
    ASSERT_FALSE(key.Open(HKEY_CURRENT_USER, kRootKey, KEY_READ));
    ASSERT_TRUE(key.Create(HKEY_CURRENT_USER, kRootKey, KEY_READ));
  }

  virtual void TearDown() {
    // Clean up the temporary key.
    RegKey key(HKEY_CURRENT_USER, L"", KEY_SET_VALUE);
    ASSERT_TRUE(key.DeleteKey(kRootKey));
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(RegistryTest);
};

TEST_F(RegistryTest, ValueTest) {
  RegKey key;

  std::wstring foo_key(kRootKey);
  foo_key += L"\\Foo";
  ASSERT_TRUE(key.Create(HKEY_CURRENT_USER, foo_key.c_str(), KEY_READ));

  {
    ASSERT_TRUE(key.Open(HKEY_CURRENT_USER, foo_key.c_str(),
                         KEY_READ | KEY_SET_VALUE));

    const wchar_t* kName = L"Bar";
    const wchar_t* kValue = L"bar";
    EXPECT_TRUE(key.WriteValue(kName, kValue));
    EXPECT_TRUE(key.ValueExists(kName));
    std::wstring out_value;
    EXPECT_TRUE(key.ReadValue(kName, &out_value));
    EXPECT_NE(out_value, L"");
    EXPECT_STREQ(out_value.c_str(), kValue);
    EXPECT_EQ(1U, key.ValueCount());
    EXPECT_TRUE(key.DeleteValue(kName));
  }
}

}  // namespace
<|endoftext|>


<commit_before>#include "clay.hpp"

namespace clay {

ExprPtr desugarCharLiteral(char c) {
    ExprPtr nameRef = prelude_expr_Char();
    CallPtr call = new Call(nameRef, new ExprList());
    ostringstream out;
    out << (int)c;
    call->parenArgs->add(new IntLiteral(out.str(), "ss"));
    return call.ptr();
}

ExprPtr desugarFieldRef(FieldRefPtr x) {
    ExprListPtr args = new ExprList(x->expr);
    args->add(new ObjectExpr(x->name.ptr()));
    CallPtr call = new Call(prelude_expr_fieldRef(), args);
    call->location = x->location;
    return call.ptr();
}

ExprPtr desugarStaticIndexing(StaticIndexingPtr x) {
    ExprListPtr args = new ExprList(x->expr);
    ValueHolderPtr vh = sizeTToValueHolder(x->index);
    args->add(new StaticExpr(new ObjectExpr(vh.ptr())));
    CallPtr call = new Call(prelude_expr_staticIndex(), args);
    call->location = x->location;
    return call.ptr();
}

ExprPtr desugarUnaryOp(UnaryOpPtr x) {
    ExprPtr callable;
    switch (x->op) {
    case DEREFERENCE :
        callable = prelude_expr_dereference();
        break;
    case ADDRESS_OF :
        callable = primitive_expr_addressOf();
        break;
    case PLUS :
        callable = prelude_expr_plus();
        break;
    case MINUS :
        callable = prelude_expr_minus();
        break;
    case NOT :
        callable = primitive_expr_boolNot();
        break;
    default :
        assert(false);
    }
    CallPtr call = new Call(callable, new ExprList());
    call->location = x->location;
    call->parenArgs->add(x->expr);
    return call.ptr();
}

ExprPtr desugarBinaryOp(BinaryOpPtr x) {
    ExprPtr callable;
    switch (x->op) {
    case ADD :
        callable = prelude_expr_add();
        break;
    case SUBTRACT :
        callable = prelude_expr_subtract();
        break;
    case MULTIPLY :
        callable = prelude_expr_multiply();
        break;
    case DIVIDE :
        callable = prelude_expr_divide();
        break;
    case REMAINDER :
        callable = prelude_expr_remainder();
        break;
    case EQUALS :
        callable = prelude_expr_equalsP();
        break;
    case NOT_EQUALS :
        callable = prelude_expr_notEqualsP();
        break;
    case LESSER :
        callable = prelude_expr_lesserP();
        break;
    case LESSER_EQUALS :
        callable = prelude_expr_lesserEqualsP();
        break;
    case GREATER :
        callable = prelude_expr_greaterP();
        break;
    case GREATER_EQUALS :
        callable = prelude_expr_greaterEqualsP();
        break;
    default :
        assert(false);
    }
    CallPtr call = new Call(callable, new ExprList());
    call->location = x->location;
    call->parenArgs->add(x->expr1);
    call->parenArgs->add(x->expr2);
    return call.ptr();
}

ExprPtr desugarIfExpr(IfExprPtr x) {
    ExprPtr callable = prelude_expr_ifExpression();
    CallPtr call = new Call(callable, new ExprList());
    call->parenArgs->add(x->condition);
    call->parenArgs->add(x->thenPart);
    call->parenArgs->add(x->elsePart);
    return call.ptr();
}

ExprPtr desugarStaticExpr(StaticExprPtr x) {
    ExprPtr callable = prelude_expr_wrapStatic();
    CallPtr call = new Call(callable, new ExprList());
    call->location = x->location;
    call->parenArgs->add(x->expr);
    return call.ptr();
}

ExprPtr updateOperatorExpr(int op) {
    switch (op) {
    case UPDATE_ADD : return prelude_expr_add();
    case UPDATE_SUBTRACT : return prelude_expr_subtract();
    case UPDATE_MULTIPLY : return prelude_expr_multiply();
    case UPDATE_DIVIDE : return prelude_expr_divide();
    case UPDATE_REMAINDER : return prelude_expr_remainder();
    default :
        assert(false);
        return NULL;
    }
}

static vector<IdentifierPtr> identV(IdentifierPtr x) {
    vector<IdentifierPtr> v;
    v.push_back(x);
    return v;
}

StatementPtr desugarForStatement(ForPtr x) {
    IdentifierPtr exprVar = new Identifier("%expr");
    exprVar->location = x->location;
    IdentifierPtr iterVar = new Identifier("%iter");
    iterVar->location = x->location;

    BlockPtr block = new Block();
    block->location = x->body->location;
    vector<StatementPtr> &bs = block->statements;
    BindingPtr exprBinding = new Binding(FORWARD, identV(exprVar), new ExprList(x->expr));
    exprBinding->location = x->body->location;
    bs.push_back(exprBinding.ptr());

    CallPtr iteratorCall = new Call(prelude_expr_iterator(), new ExprList());
    iteratorCall->location = x->body->location;
    ExprPtr exprName = new NameRef(exprVar);
    exprName->location = x->location;
    iteratorCall->parenArgs->add(exprName);
    BindingPtr iteratorBinding = new Binding(VAR,
        identV(iterVar),
        new ExprList(iteratorCall.ptr()));
    iteratorBinding->location = x->body->location;
    bs.push_back(iteratorBinding.ptr());

    CallPtr hasNextCall = new Call(prelude_expr_hasNextP(), new ExprList());
    hasNextCall->location = x->body->location;

    ExprPtr iterName = new NameRef(iterVar);
    iterName->location = x->body->location;
    hasNextCall->parenArgs->add(iterName);
    CallPtr nextCall = new Call(prelude_expr_next(), new ExprList());
    nextCall->location = x->body->location;
    nextCall->parenArgs->add(iterName);
    ExprPtr unpackNext = new Unpack(nextCall.ptr());
    unpackNext->location = x->body->location;
    BlockPtr whileBody = new Block();
    whileBody->location = x->body->location;
    vector<StatementPtr> &ws = whileBody->statements;
    ws.push_back(new Binding(FORWARD, x->variables, new ExprList(unpackNext)));
    ws.push_back(x->body);

    StatementPtr whileStmt = new While(hasNextCall.ptr(), whileBody.ptr());
    whileStmt->location = x->location;
    bs.push_back(whileStmt);
    return block.ptr();
}

StatementPtr desugarCatchBlocks(const vector<CatchPtr> &catchBlocks) {
    assert(!catchBlocks.empty());
    LocationPtr firstCatchLocation = catchBlocks.front()->location;
    IdentifierPtr expVar = new Identifier("%exp");

    CallPtr activeException = new Call(primitive_expr_activeException(), new ExprList());
    activeException->location = firstCatchLocation;

    BindingPtr expBinding =
        new Binding(VAR,
                    vector<IdentifierPtr>(1, expVar),
                    new ExprList(activeException.ptr()));
    expBinding->location = firstCatchLocation;

    bool lastWasAny = false;
    IfPtr lastIf;
    StatementPtr result;
    for (unsigned i = 0; i < catchBlocks.size(); ++i) {
        CatchPtr x = catchBlocks[i];
        if (lastWasAny)
            error(x, "unreachable catch block");
        if (x->exceptionType.ptr()) {
            ExprListPtr asTypeArgs = new ExprList(x->exceptionType);
            ExprPtr expVarName = new NameRef(expVar);
            expVarName->location = x->exceptionVar->location;
            asTypeArgs->add(expVarName);
            CallPtr cond = new Call(prelude_expr_exceptionIsP(), asTypeArgs);
            cond->location = x->exceptionType->location;

            BlockPtr block = new Block();
            block->location = x->location;
            CallPtr getter = new Call(prelude_expr_exceptionAs(), asTypeArgs);
            getter->location = x->exceptionVar->location;
            BindingPtr binding =
                new Binding(VAR,
                            vector<IdentifierPtr>(1, x->exceptionVar),
                            new ExprList(getter.ptr()));
            binding->location = x->exceptionVar->location;

            block->statements.push_back(binding.ptr());
            block->statements.push_back(x->body);

            IfPtr ifStatement = new If(cond.ptr(), block.ptr());
            ifStatement->location = x->location;
            if (!result)
                result = ifStatement.ptr();
            if (lastIf.ptr())
                lastIf->elsePart = ifStatement.ptr();
            lastIf = ifStatement;
        }
        else {
            BlockPtr block = new Block();
            block->location = x->location;
            ExprListPtr asAnyArgs = new ExprList(new NameRef(expVar));
            CallPtr getter = new Call(prelude_expr_exceptionAsAny(),
                                      asAnyArgs);
            getter->location = x->exceptionVar->location;
            BindingPtr binding =
                new Binding(VAR,
                            vector<IdentifierPtr>(1, x->exceptionVar),
                            new ExprList(getter.ptr()));
            binding->location = x->exceptionVar->location;
            block->statements.push_back(binding.ptr());
            block->statements.push_back(x->body);

            if (!result)
                result = block.ptr();
            if (lastIf.ptr())
                lastIf->elsePart = block.ptr();

            lastWasAny = true;
            lastIf = NULL;
        }
    }
    assert(result.ptr());
    if (!lastWasAny) {
        assert(lastIf.ptr());
        BlockPtr block = new Block();
        block->location = firstCatchLocation;
        ExprPtr expVarName = new NameRef(expVar);
        expVarName->location = firstCatchLocation;
        ExprListPtr continueArgs = new ExprList(expVarName);
        CallPtr continueException = new Call(prelude_expr_continueException(),
                                             continueArgs);
        continueException->location = firstCatchLocation;
        StatementPtr stmt = new ExprStatement(continueException.ptr());
        stmt->location = firstCatchLocation;
        block->statements.push_back(stmt);
        block->statements.push_back(new Unreachable());
        lastIf->elsePart = block.ptr();
    }

    BlockPtr block = new Block();
    block->location = firstCatchLocation;
    block->statements.push_back(expBinding.ptr());
    block->statements.push_back(result.ptr());

    return block.ptr();
}

StatementPtr desugarSwitchStatement(SwitchPtr x) {
    BlockPtr block = new Block();
    block->location = x->location;

    // %thing is the value being switched on
    IdentifierPtr thing = new Identifier("%case");
    thing->location = x->expr->location;
    NameRefPtr thingRef = new NameRef(thing);
    thingRef->location = x->expr->location;

    // initialize %case
    {
        BindingPtr b = new Binding(FORWARD, identV(thing), new ExprList(x->expr));
        b->location = x->expr->location;
        block->statements.push_back(b.ptr());
    }

    ExprPtr caseCallable = prelude_expr_caseP();

    StatementPtr root;
    StatementPtr *nextPtr = &root;

    // dispatch logic
    for (unsigned i = 0; i < x->caseBlocks.size(); ++i) {
        CaseBlockPtr caseBlock = x->caseBlocks[i];

        ExprListPtr caseArgs = new ExprList(thingRef.ptr());
        ExprPtr caseCompareArgs = new Paren(caseBlock->caseLabels);
        caseCompareArgs->location = caseBlock->location;
        caseArgs->add(caseCompareArgs);

        ExprPtr condition = new Call(caseCallable, caseArgs);
        condition->location = caseBlock->location;

        IfPtr ifStmt = new If(condition, caseBlock->body);
        ifStmt->location = caseBlock->location;
        *nextPtr = ifStmt.ptr();
        nextPtr = &(ifStmt->elsePart);
    }

    if (x->defaultCase.ptr())
        *nextPtr = x->defaultCase;
    else
        *nextPtr = NULL;

    block->statements.push_back(root);

    return block.ptr();
}

static SourcePtr evalToSource(LocationPtr location, ExprListPtr args, EnvPtr env)
{
    ostringstream sourceTextOut;
    MultiStaticPtr values = evaluateMultiStatic(args, env);
    for (unsigned i = 0; i < values->size(); ++i) {
        printStaticName(sourceTextOut, values->values[i]);
    }

    ostringstream sourceNameOut;
    sourceNameOut << "<eval ";
    printFileLineCol(sourceNameOut, location);
    sourceNameOut << ">";

    string sourceText = sourceTextOut.str();
    char *sourceTextData = new char[sourceText.size() + 1];
    strcpy(sourceTextData, sourceText.c_str());

    return new Source(sourceNameOut.str(), sourceTextData, sourceText.size());
}

ExprListPtr desugarEvalExpr(EvalExprPtr eval, EnvPtr env)
{
    if (eval->evaled)
        return eval->value;
    else {
        SourcePtr source = evalToSource(eval->location, new ExprList(eval->args), env);
        eval->value = parseExprList(source, 0, source->size);
        eval->evaled = true;
        return eval->value;
    }
}

vector<StatementPtr> const &desugarEvalStatement(EvalStatementPtr eval, EnvPtr env)
{
    if (eval->evaled)
        return eval->value;
    else {
        SourcePtr source = evalToSource(eval->location, eval->args, env);
        parseStatements(source, 0, source->size, eval->value);
        eval->evaled = true;
        return eval->value;
    }
}

vector<TopLevelItemPtr> const &desugarEvalTopLevel(EvalTopLevelPtr eval, EnvPtr env)
{
    if (eval->evaled)
        return eval->value;
    else {
        SourcePtr source = evalToSource(eval->location, eval->args, env);
        parseTopLevelItems(source, 0, source->size, eval->value);
        eval->evaled = true;
        return eval->value;
    }
}

static StatementPtr desugarWithBlock(WithStatementPtr with,
        const vector<StatementPtr> & statements, unsigned int i)
{
    ++i;
    BlockPtr b = new Block();
    for (; i < statements.size(); ++i) {
        StatementPtr stmt = statements[i];
        if (stmt->stmtKind == WITH) {
            b->statements.push_back(desugarWithBlock((WithStatement *)stmt.ptr(), statements, i));
            break;
        }
        b->statements.push_back(statements[i]);
    }

    vector<FormalArgPtr> formalArgs;
    for(int i = 0; i < with->identifier.size(); i++) {
        formalArgs.push_back(new FormalArg(with->identifier.at(i), NULL, TEMPNESS_DONTCARE));
    }

    FormalArgPtr formalVarArg = NULL;
    bool captureByRef = false;

    ExprPtr la = new Lambda(captureByRef, formalArgs, formalVarArg, b.ptr());
    la->location = with->withLocation;

    //append the lambda to the arguments for yield
    with->expressions->add(la);

    //form the return yield expression

    ExprListPtr rexprs = new ExprList();

    ExprPtr yieldCall = new Call(NULL, with->expressions, new ExprList());
    ExprPtr yieldName = new NameRef(new Identifier("Monad"));

    ((Call*)yieldCall.ptr())->expr = yieldName;

    rexprs->add(new Unpack(yieldCall.ptr()));

    StatementPtr r = new Return(RETURN_VALUE, rexprs);
    r->location = with->location;

    return r.ptr();
}

BlockPtr desugarBlock(BlockPtr block)
{
    for (unsigned i = 0; i < block->statements.size(); ++i) {
        StatementPtr stmt = block->statements[i];
        if (stmt->stmtKind == WITH) {
            StatementPtr stn = desugarWithBlock((WithStatement *)stmt.ptr(), block->statements, i);
            block->statements[i] = stn;
            block->statements.resize( i + 1);
            break;
        }
    }
    return block;
}

}
<commit_msg>desugar with: the library function should be lowercase<commit_after>#include "clay.hpp"

namespace clay {

ExprPtr desugarCharLiteral(char c) {
    ExprPtr nameRef = prelude_expr_Char();
    CallPtr call = new Call(nameRef, new ExprList());
    ostringstream out;
    out << (int)c;
    call->parenArgs->add(new IntLiteral(out.str(), "ss"));
    return call.ptr();
}

ExprPtr desugarFieldRef(FieldRefPtr x) {
    ExprListPtr args = new ExprList(x->expr);
    args->add(new ObjectExpr(x->name.ptr()));
    CallPtr call = new Call(prelude_expr_fieldRef(), args);
    call->location = x->location;
    return call.ptr();
}

ExprPtr desugarStaticIndexing(StaticIndexingPtr x) {
    ExprListPtr args = new ExprList(x->expr);
    ValueHolderPtr vh = sizeTToValueHolder(x->index);
    args->add(new StaticExpr(new ObjectExpr(vh.ptr())));
    CallPtr call = new Call(prelude_expr_staticIndex(), args);
    call->location = x->location;
    return call.ptr();
}

ExprPtr desugarUnaryOp(UnaryOpPtr x) {
    ExprPtr callable;
    switch (x->op) {
    case DEREFERENCE :
        callable = prelude_expr_dereference();
        break;
    case ADDRESS_OF :
        callable = primitive_expr_addressOf();
        break;
    case PLUS :
        callable = prelude_expr_plus();
        break;
    case MINUS :
        callable = prelude_expr_minus();
        break;
    case NOT :
        callable = primitive_expr_boolNot();
        break;
    default :
        assert(false);
    }
    CallPtr call = new Call(callable, new ExprList());
    call->location = x->location;
    call->parenArgs->add(x->expr);
    return call.ptr();
}

ExprPtr desugarBinaryOp(BinaryOpPtr x) {
    ExprPtr callable;
    switch (x->op) {
    case ADD :
        callable = prelude_expr_add();
        break;
    case SUBTRACT :
        callable = prelude_expr_subtract();
        break;
    case MULTIPLY :
        callable = prelude_expr_multiply();
        break;
    case DIVIDE :
        callable = prelude_expr_divide();
        break;
    case REMAINDER :
        callable = prelude_expr_remainder();
        break;
    case EQUALS :
        callable = prelude_expr_equalsP();
        break;
    case NOT_EQUALS :
        callable = prelude_expr_notEqualsP();
        break;
    case LESSER :
        callable = prelude_expr_lesserP();
        break;
    case LESSER_EQUALS :
        callable = prelude_expr_lesserEqualsP();
        break;
    case GREATER :
        callable = prelude_expr_greaterP();
        break;
    case GREATER_EQUALS :
        callable = prelude_expr_greaterEqualsP();
        break;
    default :
        assert(false);
    }
    CallPtr call = new Call(callable, new ExprList());
    call->location = x->location;
    call->parenArgs->add(x->expr1);
    call->parenArgs->add(x->expr2);
    return call.ptr();
}

ExprPtr desugarIfExpr(IfExprPtr x) {
    ExprPtr callable = prelude_expr_ifExpression();
    CallPtr call = new Call(callable, new ExprList());
    call->parenArgs->add(x->condition);
    call->parenArgs->add(x->thenPart);
    call->parenArgs->add(x->elsePart);
    return call.ptr();
}

ExprPtr desugarStaticExpr(StaticExprPtr x) {
    ExprPtr callable = prelude_expr_wrapStatic();
    CallPtr call = new Call(callable, new ExprList());
    call->location = x->location;
    call->parenArgs->add(x->expr);
    return call.ptr();
}

ExprPtr updateOperatorExpr(int op) {
    switch (op) {
    case UPDATE_ADD : return prelude_expr_add();
    case UPDATE_SUBTRACT : return prelude_expr_subtract();
    case UPDATE_MULTIPLY : return prelude_expr_multiply();
    case UPDATE_DIVIDE : return prelude_expr_divide();
    case UPDATE_REMAINDER : return prelude_expr_remainder();
    default :
        assert(false);
        return NULL;
    }
}

static vector<IdentifierPtr> identV(IdentifierPtr x) {
    vector<IdentifierPtr> v;
    v.push_back(x);
    return v;
}

StatementPtr desugarForStatement(ForPtr x) {
    IdentifierPtr exprVar = new Identifier("%expr");
    exprVar->location = x->location;
    IdentifierPtr iterVar = new Identifier("%iter");
    iterVar->location = x->location;

    BlockPtr block = new Block();
    block->location = x->body->location;
    vector<StatementPtr> &bs = block->statements;
    BindingPtr exprBinding = new Binding(FORWARD, identV(exprVar), new ExprList(x->expr));
    exprBinding->location = x->body->location;
    bs.push_back(exprBinding.ptr());

    CallPtr iteratorCall = new Call(prelude_expr_iterator(), new ExprList());
    iteratorCall->location = x->body->location;
    ExprPtr exprName = new NameRef(exprVar);
    exprName->location = x->location;
    iteratorCall->parenArgs->add(exprName);
    BindingPtr iteratorBinding = new Binding(VAR,
        identV(iterVar),
        new ExprList(iteratorCall.ptr()));
    iteratorBinding->location = x->body->location;
    bs.push_back(iteratorBinding.ptr());

    CallPtr hasNextCall = new Call(prelude_expr_hasNextP(), new ExprList());
    hasNextCall->location = x->body->location;

    ExprPtr iterName = new NameRef(iterVar);
    iterName->location = x->body->location;
    hasNextCall->parenArgs->add(iterName);
    CallPtr nextCall = new Call(prelude_expr_next(), new ExprList());
    nextCall->location = x->body->location;
    nextCall->parenArgs->add(iterName);
    ExprPtr unpackNext = new Unpack(nextCall.ptr());
    unpackNext->location = x->body->location;
    BlockPtr whileBody = new Block();
    whileBody->location = x->body->location;
    vector<StatementPtr> &ws = whileBody->statements;
    ws.push_back(new Binding(FORWARD, x->variables, new ExprList(unpackNext)));
    ws.push_back(x->body);

    StatementPtr whileStmt = new While(hasNextCall.ptr(), whileBody.ptr());
    whileStmt->location = x->location;
    bs.push_back(whileStmt);
    return block.ptr();
}

StatementPtr desugarCatchBlocks(const vector<CatchPtr> &catchBlocks) {
    assert(!catchBlocks.empty());
    LocationPtr firstCatchLocation = catchBlocks.front()->location;
    IdentifierPtr expVar = new Identifier("%exp");

    CallPtr activeException = new Call(primitive_expr_activeException(), new ExprList());
    activeException->location = firstCatchLocation;

    BindingPtr expBinding =
        new Binding(VAR,
                    vector<IdentifierPtr>(1, expVar),
                    new ExprList(activeException.ptr()));
    expBinding->location = firstCatchLocation;

    bool lastWasAny = false;
    IfPtr lastIf;
    StatementPtr result;
    for (unsigned i = 0; i < catchBlocks.size(); ++i) {
        CatchPtr x = catchBlocks[i];
        if (lastWasAny)
            error(x, "unreachable catch block");
        if (x->exceptionType.ptr()) {
            ExprListPtr asTypeArgs = new ExprList(x->exceptionType);
            ExprPtr expVarName = new NameRef(expVar);
            expVarName->location = x->exceptionVar->location;
            asTypeArgs->add(expVarName);
            CallPtr cond = new Call(prelude_expr_exceptionIsP(), asTypeArgs);
            cond->location = x->exceptionType->location;

            BlockPtr block = new Block();
            block->location = x->location;
            CallPtr getter = new Call(prelude_expr_exceptionAs(), asTypeArgs);
            getter->location = x->exceptionVar->location;
            BindingPtr binding =
                new Binding(VAR,
                            vector<IdentifierPtr>(1, x->exceptionVar),
                            new ExprList(getter.ptr()));
            binding->location = x->exceptionVar->location;

            block->statements.push_back(binding.ptr());
            block->statements.push_back(x->body);

            IfPtr ifStatement = new If(cond.ptr(), block.ptr());
            ifStatement->location = x->location;
            if (!result)
                result = ifStatement.ptr();
            if (lastIf.ptr())
                lastIf->elsePart = ifStatement.ptr();
            lastIf = ifStatement;
        }
        else {
            BlockPtr block = new Block();
            block->location = x->location;
            ExprListPtr asAnyArgs = new ExprList(new NameRef(expVar));
            CallPtr getter = new Call(prelude_expr_exceptionAsAny(),
                                      asAnyArgs);
            getter->location = x->exceptionVar->location;
            BindingPtr binding =
                new Binding(VAR,
                            vector<IdentifierPtr>(1, x->exceptionVar),
                            new ExprList(getter.ptr()));
            binding->location = x->exceptionVar->location;
            block->statements.push_back(binding.ptr());
            block->statements.push_back(x->body);

            if (!result)
                result = block.ptr();
            if (lastIf.ptr())
                lastIf->elsePart = block.ptr();

            lastWasAny = true;
            lastIf = NULL;
        }
    }
    assert(result.ptr());
    if (!lastWasAny) {
        assert(lastIf.ptr());
        BlockPtr block = new Block();
        block->location = firstCatchLocation;
        ExprPtr expVarName = new NameRef(expVar);
        expVarName->location = firstCatchLocation;
        ExprListPtr continueArgs = new ExprList(expVarName);
        CallPtr continueException = new Call(prelude_expr_continueException(),
                                             continueArgs);
        continueException->location = firstCatchLocation;
        StatementPtr stmt = new ExprStatement(continueException.ptr());
        stmt->location = firstCatchLocation;
        block->statements.push_back(stmt);
        block->statements.push_back(new Unreachable());
        lastIf->elsePart = block.ptr();
    }

    BlockPtr block = new Block();
    block->location = firstCatchLocation;
    block->statements.push_back(expBinding.ptr());
    block->statements.push_back(result.ptr());

    return block.ptr();
}

StatementPtr desugarSwitchStatement(SwitchPtr x) {
    BlockPtr block = new Block();
    block->location = x->location;

    // %thing is the value being switched on
    IdentifierPtr thing = new Identifier("%case");
    thing->location = x->expr->location;
    NameRefPtr thingRef = new NameRef(thing);
    thingRef->location = x->expr->location;

    // initialize %case
    {
        BindingPtr b = new Binding(FORWARD, identV(thing), new ExprList(x->expr));
        b->location = x->expr->location;
        block->statements.push_back(b.ptr());
    }

    ExprPtr caseCallable = prelude_expr_caseP();

    StatementPtr root;
    StatementPtr *nextPtr = &root;

    // dispatch logic
    for (unsigned i = 0; i < x->caseBlocks.size(); ++i) {
        CaseBlockPtr caseBlock = x->caseBlocks[i];

        ExprListPtr caseArgs = new ExprList(thingRef.ptr());
        ExprPtr caseCompareArgs = new Paren(caseBlock->caseLabels);
        caseCompareArgs->location = caseBlock->location;
        caseArgs->add(caseCompareArgs);

        ExprPtr condition = new Call(caseCallable, caseArgs);
        condition->location = caseBlock->location;

        IfPtr ifStmt = new If(condition, caseBlock->body);
        ifStmt->location = caseBlock->location;
        *nextPtr = ifStmt.ptr();
        nextPtr = &(ifStmt->elsePart);
    }

    if (x->defaultCase.ptr())
        *nextPtr = x->defaultCase;
    else
        *nextPtr = NULL;

    block->statements.push_back(root);

    return block.ptr();
}

static SourcePtr evalToSource(LocationPtr location, ExprListPtr args, EnvPtr env)
{
    ostringstream sourceTextOut;
    MultiStaticPtr values = evaluateMultiStatic(args, env);
    for (unsigned i = 0; i < values->size(); ++i) {
        printStaticName(sourceTextOut, values->values[i]);
    }

    ostringstream sourceNameOut;
    sourceNameOut << "<eval ";
    printFileLineCol(sourceNameOut, location);
    sourceNameOut << ">";

    string sourceText = sourceTextOut.str();
    char *sourceTextData = new char[sourceText.size() + 1];
    strcpy(sourceTextData, sourceText.c_str());

    return new Source(sourceNameOut.str(), sourceTextData, sourceText.size());
}

ExprListPtr desugarEvalExpr(EvalExprPtr eval, EnvPtr env)
{
    if (eval->evaled)
        return eval->value;
    else {
        SourcePtr source = evalToSource(eval->location, new ExprList(eval->args), env);
        eval->value = parseExprList(source, 0, source->size);
        eval->evaled = true;
        return eval->value;
    }
}

vector<StatementPtr> const &desugarEvalStatement(EvalStatementPtr eval, EnvPtr env)
{
    if (eval->evaled)
        return eval->value;
    else {
        SourcePtr source = evalToSource(eval->location, eval->args, env);
        parseStatements(source, 0, source->size, eval->value);
        eval->evaled = true;
        return eval->value;
    }
}

vector<TopLevelItemPtr> const &desugarEvalTopLevel(EvalTopLevelPtr eval, EnvPtr env)
{
    if (eval->evaled)
        return eval->value;
    else {
        SourcePtr source = evalToSource(eval->location, eval->args, env);
        parseTopLevelItems(source, 0, source->size, eval->value);
        eval->evaled = true;
        return eval->value;
    }
}

static StatementPtr desugarWithBlock(WithStatementPtr with,
        const vector<StatementPtr> & statements, unsigned int i)
{
    ++i;
    BlockPtr b = new Block();
    for (; i < statements.size(); ++i) {
        StatementPtr stmt = statements[i];
        if (stmt->stmtKind == WITH) {
            b->statements.push_back(desugarWithBlock((WithStatement *)stmt.ptr(), statements, i));
            break;
        }
        b->statements.push_back(statements[i]);
    }

    vector<FormalArgPtr> formalArgs;
    for(int i = 0; i < with->identifier.size(); i++) {
        formalArgs.push_back(new FormalArg(with->identifier.at(i), NULL, TEMPNESS_DONTCARE));
    }

    FormalArgPtr formalVarArg = NULL;
    bool captureByRef = false;

    ExprPtr la = new Lambda(captureByRef, formalArgs, formalVarArg, b.ptr());
    la->location = with->withLocation;

    //append the lambda to the arguments for yield
    with->expressions->add(la);

    //form the return yield expression

    ExprListPtr rexprs = new ExprList();

    ExprPtr yieldCall = new Call(NULL, with->expressions, new ExprList());
    ExprPtr yieldName = new NameRef(new Identifier("monad"));

    ((Call*)yieldCall.ptr())->expr = yieldName;

    rexprs->add(new Unpack(yieldCall.ptr()));

    StatementPtr r = new Return(RETURN_VALUE, rexprs);
    r->location = with->location;

    return r.ptr();
}

BlockPtr desugarBlock(BlockPtr block)
{
    for (unsigned i = 0; i < block->statements.size(); ++i) {
        StatementPtr stmt = block->statements[i];
        if (stmt->stmtKind == WITH) {
            StatementPtr stn = desugarWithBlock((WithStatement *)stmt.ptr(), block->statements, i);
            block->statements[i] = stn;
            block->statements.resize( i + 1);
            break;
        }
    }
    return block;
}

}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: Vesa-Matti Hartikainen <vesa-matti.hartikainen@jollamobile.com>
**
****************************************************************************/

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "declarativebookmarkmodel.h"
#include "bookmarkmanager.h"

DeclarativeBookmarkModel::DeclarativeBookmarkModel(QObject *parent) :
    QAbstractListModel(parent)
{
    connect(BookmarkManager::instance(), SIGNAL(cleared()), this, SLOT(clearBookmarks()));
    bookmarks = BookmarkManager::instance()->load();

    // Generate mapping URL -> bookmark's index in the loaded list.
    int index(0);
    foreach (Bookmark* bookmark, bookmarks) {
        bookmarkIndexes.insert(bookmark->url(), index);
        index++;
    }
}

QHash<int, QByteArray> DeclarativeBookmarkModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[UrlRole] = "url";
    roles[TitleRole] = "title";
    roles[FaviconRole] = "favicon";
    roles[TouchIconRole] = "hasTouchIcon";
    return roles;
}

void DeclarativeBookmarkModel::addBookmark(const QString& url, const QString& title, const QString& favicon, bool touchIcon)
{
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    bookmarkIndexes.insert(url, bookmarks.count());
    bookmarks.append(new Bookmark(title, url, favicon, touchIcon));
    endInsertRows();

    emit countChanged();
    save();
}

void DeclarativeBookmarkModel::removeBookmark(const QString& url)
{
    if (!contains(url)) {
        return;
    }

    if (bookmarkIndexes.keys().contains(url)) {
        int index = bookmarkIndexes.value(url);
        beginRemoveRows(QModelIndex(), index, index);
        Bookmark* bookmark = bookmarks.takeAt(index);
        delete bookmark;
        bookmarkIndexes.remove(url);
        endRemoveRows();

        emit countChanged();
        save();
    }
}

void DeclarativeBookmarkModel::editBookmark(int index, const QString& url, const QString& title)
{
    if (index < 0 || index > bookmarks.count())
        return;

    Bookmark * bookmark = bookmarks.value(index);
    QVector<int> roles;
    if (url != bookmark->url()) {
        bookmark->setUrl(url);
        roles << UrlRole;
    }
    if (title != bookmark->title()) {
        bookmark->setTitle(title);
        roles << TitleRole;
    }
    if (roles.count() > 0) {
        QModelIndex modelIndex = QAbstractListModel::index(index);
        emit dataChanged(modelIndex, modelIndex, roles);
        save();
    }
}

void DeclarativeBookmarkModel::clearBookmarks()
{
    beginRemoveRows(QModelIndex(), 0, bookmarks.count()-1);
    bookmarks.clear();
    bookmarkIndexes.clear();
    endRemoveRows();
    emit countChanged();
}

void DeclarativeBookmarkModel::save()
{
    BookmarkManager::instance()->save(bookmarks);
}

int DeclarativeBookmarkModel::rowCount(const QModelIndex & parent) const
{
    Q_UNUSED(parent)
    return bookmarks.count();
}

QVariant DeclarativeBookmarkModel::data(const QModelIndex & index, int role) const
{
    if (index.row() < 0 || index.row() > bookmarks.count())
        return QVariant();

    const Bookmark * bookmark = bookmarks.value(index.row());
    if (role == UrlRole) {
        return bookmark->url();
    } else if (role == TitleRole) {
        return bookmark->title();
    } else if (role == FaviconRole) {
        return bookmark->favicon();
    } else if (role == TouchIconRole) {
        return bookmark->hasTouchIcon();
    }
    return QVariant();
}

bool DeclarativeBookmarkModel::contains(const QString& url) const
{
    return bookmarkIndexes.contains(url);
}
<commit_msg>[sailfish-browser] Update bookmarkIndexes map after bookmark is removed. Fixes JB#29051<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: Vesa-Matti Hartikainen <vesa-matti.hartikainen@jollamobile.com>
**
****************************************************************************/

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "declarativebookmarkmodel.h"
#include "bookmarkmanager.h"

DeclarativeBookmarkModel::DeclarativeBookmarkModel(QObject *parent) :
    QAbstractListModel(parent)
{
    connect(BookmarkManager::instance(), SIGNAL(cleared()), this, SLOT(clearBookmarks()));
    bookmarks = BookmarkManager::instance()->load();

    // Generate mapping URL -> bookmark's index in the loaded list.
    int index(0);
    foreach (Bookmark* bookmark, bookmarks) {
        bookmarkIndexes.insert(bookmark->url(), index);
        index++;
    }
}

QHash<int, QByteArray> DeclarativeBookmarkModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[UrlRole] = "url";
    roles[TitleRole] = "title";
    roles[FaviconRole] = "favicon";
    roles[TouchIconRole] = "hasTouchIcon";
    return roles;
}

void DeclarativeBookmarkModel::addBookmark(const QString& url, const QString& title, const QString& favicon, bool touchIcon)
{
    beginInsertRows(QModelIndex(), rowCount(), rowCount());
    bookmarkIndexes.insert(url, bookmarks.count());
    bookmarks.append(new Bookmark(title, url, favicon, touchIcon));
    endInsertRows();

    emit countChanged();
    save();
}

void DeclarativeBookmarkModel::removeBookmark(const QString& url)
{
    if (!contains(url)) {
        return;
    }

    if (bookmarkIndexes.keys().contains(url)) {
        int index = bookmarkIndexes.value(url);
        beginRemoveRows(QModelIndex(), index, index);
        Bookmark* bookmark = bookmarks.takeAt(index);
        delete bookmark;

        // Remove index mapping and update remaining indices
        bookmarkIndexes.remove(url);
        QMap<QString, int>::iterator i = bookmarkIndexes.begin();
        while (i != bookmarkIndexes.end()) {
            if (i.value() > index) {
                i.value()--;
            }
            i++;
        }

        endRemoveRows();

        emit countChanged();
        save();
    }
}

void DeclarativeBookmarkModel::editBookmark(int index, const QString& url, const QString& title)
{
    if (index < 0 || index > bookmarks.count())
        return;

    Bookmark * bookmark = bookmarks.value(index);
    QVector<int> roles;
    if (url != bookmark->url()) {
        bookmark->setUrl(url);
        roles << UrlRole;
    }
    if (title != bookmark->title()) {
        bookmark->setTitle(title);
        roles << TitleRole;
    }
    if (roles.count() > 0) {
        QModelIndex modelIndex = QAbstractListModel::index(index);
        emit dataChanged(modelIndex, modelIndex, roles);
        save();
    }
}

void DeclarativeBookmarkModel::clearBookmarks()
{
    beginRemoveRows(QModelIndex(), 0, bookmarks.count()-1);
    bookmarks.clear();
    bookmarkIndexes.clear();
    endRemoveRows();
    emit countChanged();
}

void DeclarativeBookmarkModel::save()
{
    BookmarkManager::instance()->save(bookmarks);
}

int DeclarativeBookmarkModel::rowCount(const QModelIndex & parent) const
{
    Q_UNUSED(parent)
    return bookmarks.count();
}

QVariant DeclarativeBookmarkModel::data(const QModelIndex & index, int role) const
{
    if (index.row() < 0 || index.row() > bookmarks.count())
        return QVariant();

    const Bookmark * bookmark = bookmarks.value(index.row());
    if (role == UrlRole) {
        return bookmark->url();
    } else if (role == TitleRole) {
        return bookmark->title();
    } else if (role == FaviconRole) {
        return bookmark->favicon();
    } else if (role == TouchIconRole) {
        return bookmark->hasTouchIcon();
    }
    return QVariant();
}

bool DeclarativeBookmarkModel::contains(const QString& url) const
{
    return bookmarkIndexes.contains(url);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: textlayout.cxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_canvas.hxx"

#include <canvas/debug.hxx>
#include <canvas/canvastools.hxx>

#include <com/sun/star/rendering/TextDirection.hpp>

#include <vcl/metric.hxx>
#include <vcl/virdev.hxx>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/numeric/ftools.hxx>

#include "impltools.hxx"
#include "textlayout.hxx"

#include <boost/scoped_array.hpp>

using namespace ::com::sun::star;

namespace vclcanvas
{
    namespace
    {
        void setupLayoutMode( OutputDevice& rOutDev,
                              sal_Int8      nTextDirection )
        {
            // TODO(P3): avoid if already correctly set
            ULONG nLayoutMode;
            switch( nTextDirection )
            {
                default:
                    nLayoutMode = 0;
                    break;
                case rendering::TextDirection::WEAK_LEFT_TO_RIGHT:
                    nLayoutMode = TEXT_LAYOUT_BIDI_LTR;
                    break;
                case rendering::TextDirection::STRONG_LEFT_TO_RIGHT:
                    nLayoutMode = TEXT_LAYOUT_BIDI_LTR | TEXT_LAYOUT_BIDI_STRONG;
                    break;
                case rendering::TextDirection::WEAK_RIGHT_TO_LEFT:
                    nLayoutMode = TEXT_LAYOUT_BIDI_RTL;
                    break;
                case rendering::TextDirection::STRONG_RIGHT_TO_LEFT:
                    nLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_BIDI_STRONG;
                    break;
            }

            // set calculated layout mode. Origin is always the left edge,
            // as required at the API spec
            rOutDev.SetLayoutMode( nLayoutMode | TEXT_LAYOUT_TEXTORIGIN_LEFT );
        }
    }

    TextLayout::TextLayout( const rendering::StringContext& aText,
                            sal_Int8                        nDirection,
                            sal_Int64                       nRandomSeed,
                            const CanvasFont::Reference&    rFont,
                            const DeviceRef&                rRefDevice ) :
        TextLayout_Base( m_aMutex ),
        maText( aText ),
        maLogicalAdvancements(),
        mpFont( rFont ),
        mpRefDevice( rRefDevice ),
        mnTextDirection( nDirection )
    {
        (void)nRandomSeed;
    }

    void SAL_CALL TextLayout::disposing()
    {
        tools::LocalGuard aGuard;

        mpFont.reset();
        mpRefDevice.clear();
    }

    // XTextLayout
    uno::Sequence< uno::Reference< rendering::XPolyPolygon2D > > SAL_CALL TextLayout::queryTextShapes(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        // TODO(F1)
        return uno::Sequence< uno::Reference< rendering::XPolyPolygon2D > >();
    }

    uno::Sequence< geometry::RealRectangle2D > SAL_CALL TextLayout::queryInkMeasures(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        // TODO(F1)
        return uno::Sequence< geometry::RealRectangle2D >();
    }

    uno::Sequence< geometry::RealRectangle2D > SAL_CALL TextLayout::queryMeasures(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        // TODO(F1)
        return uno::Sequence< geometry::RealRectangle2D >();
    }

    uno::Sequence< double > SAL_CALL TextLayout::queryLogicalAdvancements(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        return maLogicalAdvancements;
    }

    void SAL_CALL TextLayout::applyLogicalAdvancements( const uno::Sequence< double >& aAdvancements ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        CHECK_AND_THROW( aAdvancements.getLength() == maText.Length,
                         "TextLayout::applyLogicalAdvancements(): mismatching number of advancements" );

        maLogicalAdvancements = aAdvancements;
    }

    geometry::RealRectangle2D SAL_CALL TextLayout::queryTextBounds(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        OutputDevice* pOutDev = mpRefDevice->getOutDev();
        if( !pOutDev )
            return geometry::RealRectangle2D();

        VirtualDevice aVDev( *pOutDev );
        aVDev.SetFont( mpFont->getVCLFont() );

        // need metrics for Y offset, the XCanvas always renders
        // relative to baseline
        const ::FontMetric& aMetric( aVDev.GetFontMetric() );

        setupLayoutMode( aVDev, mnTextDirection );

        const sal_Int32 nAboveBaseline( -aMetric.GetIntLeading() - aMetric.GetAscent() );
        const sal_Int32 nBelowBaseline( aMetric.GetDescent() );

        if( maLogicalAdvancements.getLength() )
        {
            return geometry::RealRectangle2D( 0, nAboveBaseline,
                                              maLogicalAdvancements[ maLogicalAdvancements.getLength()-1 ],
                                              nBelowBaseline );
        }
        else
        {
            return geometry::RealRectangle2D( 0, nAboveBaseline,
                                              aVDev.GetTextWidth(
                                                  maText.Text,
                                                  ::canvas::tools::numeric_cast<USHORT>(maText.StartPosition),
                                                  ::canvas::tools::numeric_cast<USHORT>(maText.Length) ),
                                              nBelowBaseline );
        }
    }

    double SAL_CALL TextLayout::justify( double nSize ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)nSize;

        // TODO(F1)
        return 0.0;
    }

    double SAL_CALL TextLayout::combinedJustify( const uno::Sequence< uno::Reference< rendering::XTextLayout > >& aNextLayouts,
                                                 double                                                           nSize ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)aNextLayouts;
        (void)nSize;

        // TODO(F1)
        return 0.0;
    }

    rendering::TextHit SAL_CALL TextLayout::getTextHit( const geometry::RealPoint2D& aHitPoint ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)aHitPoint;

        // TODO(F1)
        return rendering::TextHit();
    }

    rendering::Caret SAL_CALL TextLayout::getCaret( sal_Int32 nInsertionIndex, sal_Bool bExcludeLigatures ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)nInsertionIndex;
        (void)bExcludeLigatures;

        // TODO(F1)
        return rendering::Caret();
    }

    sal_Int32 SAL_CALL TextLayout::getNextInsertionIndex( sal_Int32 nStartIndex, sal_Int32 nCaretAdvancement, sal_Bool bExcludeLigatures ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)nStartIndex;
        (void)nCaretAdvancement;
        (void)bExcludeLigatures;

        // TODO(F1)
        return 0;
    }

    uno::Reference< rendering::XPolyPolygon2D > SAL_CALL TextLayout::queryVisualHighlighting( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)nStartIndex;
        (void)nEndIndex;

        // TODO(F1)
        return uno::Reference< rendering::XPolyPolygon2D >();
    }

    uno::Reference< rendering::XPolyPolygon2D > SAL_CALL TextLayout::queryLogicalHighlighting( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)nStartIndex;
        (void)nEndIndex;

        // TODO(F1)
        return uno::Reference< rendering::XPolyPolygon2D >();
    }

    double SAL_CALL TextLayout::getBaselineOffset(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        // TODO(F1)
        return 0.0;
    }

    sal_Int8 SAL_CALL TextLayout::getMainTextDirection(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        return mnTextDirection;
    }

    uno::Reference< rendering::XCanvasFont > SAL_CALL TextLayout::getFont(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        return mpFont.getRef();
    }

    rendering::StringContext SAL_CALL TextLayout::getText(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        return maText;
    }

    bool TextLayout::draw( OutputDevice&                 rOutDev,
                           const Point&                  rOutpos,
                           const rendering::ViewState&   viewState,
                           const rendering::RenderState& renderState ) const
    {
        tools::LocalGuard aGuard;

        setupLayoutMode( rOutDev, mnTextDirection );

        if( maLogicalAdvancements.getLength() )
        {
            // TODO(P2): cache that
            ::boost::scoped_array< sal_Int32 > aOffsets(new sal_Int32[maLogicalAdvancements.getLength()]);
            setupTextOffsets( aOffsets.get(), maLogicalAdvancements, viewState, renderState );

            // TODO(F3): ensure correct length and termination for DX
            // array (last entry _must_ contain the overall width)

            rOutDev.DrawTextArray( rOutpos,
                                   maText.Text,
                                   aOffsets.get(),
                                   ::canvas::tools::numeric_cast<USHORT>(maText.StartPosition),
                                   ::canvas::tools::numeric_cast<USHORT>(maText.Length) );
        }
        else
        {
            rOutDev.DrawText( rOutpos,
                              maText.Text,
                              ::canvas::tools::numeric_cast<USHORT>(maText.StartPosition),
                              ::canvas::tools::numeric_cast<USHORT>(maText.Length) );
        }

        return true;
    }

    namespace
    {
        class OffsetTransformer
        {
        public:
            OffsetTransformer( const ::basegfx::B2DHomMatrix& rMat ) :
                maMatrix( rMat )
            {
            }

            sal_Int32 operator()( const double& rOffset )
            {
                // This is an optimization of the normal rMat*[x,0]
                // transformation of the advancement vector (in x
                // direction), followed by a length calculation of the
                // resulting vector: advancement' =
                // ||rMat*[x,0]||. Since advancements are vectors, we
                // can ignore translational components, thus if [x,0],
                // it follows that rMat*[x,0]=[x',0] holds. Thus, we
                // just have to calc the transformation of the x
                // component.

                // TODO(F2): Handle non-horizontal advancements!
                return ::basegfx::fround( hypot(maMatrix.get(0,0)*rOffset,
                                                maMatrix.get(1,0)*rOffset) );
            }

        private:
            ::basegfx::B2DHomMatrix maMatrix;
        };
    }

    void TextLayout::setupTextOffsets( sal_Int32*                       outputOffsets,
                                       const uno::Sequence< double >&   inputOffsets,
                                       const rendering::ViewState&      viewState,
                                       const rendering::RenderState&    renderState     ) const
    {
        ENSURE_AND_THROW( outputOffsets!=NULL,
                          "TextLayout::setupTextOffsets offsets NULL" );

        ::basegfx::B2DHomMatrix aMatrix;

        ::canvas::tools::mergeViewAndRenderTransform(aMatrix,
                                                     viewState,
                                                     renderState);

        // fill integer offsets
        ::std::transform( const_cast< uno::Sequence< double >& >(inputOffsets).getConstArray(),
                          const_cast< uno::Sequence< double >& >(inputOffsets).getConstArray()+inputOffsets.getLength(),
                          outputOffsets,
                          OffsetTransformer( aMatrix ) );
    }

#define IMPLEMENTATION_NAME "VCLCanvas::TextLayout"
#define SERVICE_NAME "com.sun.star.rendering.TextLayout"

    ::rtl::OUString SAL_CALL TextLayout::getImplementationName() throw( uno::RuntimeException )
    {
        return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
    }

    sal_Bool SAL_CALL TextLayout::supportsService( const ::rtl::OUString& ServiceName ) throw( uno::RuntimeException )
    {
        return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) );
    }

    uno::Sequence< ::rtl::OUString > SAL_CALL TextLayout::getSupportedServiceNames()  throw( uno::RuntimeException )
    {
        uno::Sequence< ::rtl::OUString > aRet(1);
        aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );

        return aRet;
    }
}
<commit_msg>INTEGRATION: CWS canvas05 (1.8.68); FILE MERGED 2008/04/21 07:28:56 thb 1.8.68.3: RESYNC: (1.8-1.9); FILE MERGED 2007/12/20 22:19:00 thb 1.8.68.2: #i81092# #i78888# #i78925# #i79258# #i79437# #i84784# Large canvas rework, completing various areas such as color spaces, bitmap data access, true sprite and non-sprite implementations, and upstreaming the canvas parts of rodos emf+ rendering 2007/10/01 13:02:04 thb 1.8.68.1: #i78888# #i78925# #i79258# #i79437# Merge from CWS picom<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: textlayout.cxx,v $
 * $Revision: 1.10 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_canvas.hxx"

#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>
#include <canvas/canvastools.hxx>

#include <com/sun/star/rendering/TextDirection.hpp>

#include <vcl/metric.hxx>
#include <vcl/virdev.hxx>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/numeric/ftools.hxx>

#include "impltools.hxx"
#include "textlayout.hxx"

#include <boost/scoped_array.hpp>

using namespace ::com::sun::star;

namespace vclcanvas
{
    namespace
    {
        void setupLayoutMode( OutputDevice& rOutDev,
                              sal_Int8      nTextDirection )
        {
            // TODO(P3): avoid if already correctly set
            ULONG nLayoutMode;
            switch( nTextDirection )
            {
                default:
                    nLayoutMode = 0;
                    break;
                case rendering::TextDirection::WEAK_LEFT_TO_RIGHT:
                    nLayoutMode = TEXT_LAYOUT_BIDI_LTR;
                    break;
                case rendering::TextDirection::STRONG_LEFT_TO_RIGHT:
                    nLayoutMode = TEXT_LAYOUT_BIDI_LTR | TEXT_LAYOUT_BIDI_STRONG;
                    break;
                case rendering::TextDirection::WEAK_RIGHT_TO_LEFT:
                    nLayoutMode = TEXT_LAYOUT_BIDI_RTL;
                    break;
                case rendering::TextDirection::STRONG_RIGHT_TO_LEFT:
                    nLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_BIDI_STRONG;
                    break;
            }

            // set calculated layout mode. Origin is always the left edge,
            // as required at the API spec
            rOutDev.SetLayoutMode( nLayoutMode | TEXT_LAYOUT_TEXTORIGIN_LEFT );
        }
    }

    TextLayout::TextLayout( const rendering::StringContext&                  aText,
                            sal_Int8                                         nDirection,
                            sal_Int64                                        nRandomSeed,
                            const CanvasFont::Reference&                     rFont,
                            const uno::Reference<rendering::XGraphicDevice>& xDevice,
                            const OutDevProviderSharedPtr&                   rOutDev ) :
        TextLayout_Base( m_aMutex ),
        maText( aText ),
        maLogicalAdvancements(),
        mpFont( rFont ),
        mxDevice( xDevice ),
        mpOutDevProvider( rOutDev ),
        mnTextDirection( nDirection )
    {
        (void)nRandomSeed;
    }

    void SAL_CALL TextLayout::disposing()
    {
        tools::LocalGuard aGuard;

        mpOutDevProvider.reset();
        mxDevice.clear();
        mpFont.reset();
    }

    // XTextLayout
    uno::Sequence< uno::Reference< rendering::XPolyPolygon2D > > SAL_CALL TextLayout::queryTextShapes(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        // TODO(F1)
        return uno::Sequence< uno::Reference< rendering::XPolyPolygon2D > >();
    }

    uno::Sequence< geometry::RealRectangle2D > SAL_CALL TextLayout::queryInkMeasures(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        // TODO(F1)
        return uno::Sequence< geometry::RealRectangle2D >();
    }

    uno::Sequence< geometry::RealRectangle2D > SAL_CALL TextLayout::queryMeasures(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        // TODO(F1)
        return uno::Sequence< geometry::RealRectangle2D >();
    }

    uno::Sequence< double > SAL_CALL TextLayout::queryLogicalAdvancements(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        return maLogicalAdvancements;
    }

    void SAL_CALL TextLayout::applyLogicalAdvancements( const uno::Sequence< double >& aAdvancements ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        ENSURE_ARG_OR_THROW( aAdvancements.getLength() == maText.Length,
                         "TextLayout::applyLogicalAdvancements(): mismatching number of advancements" );

        maLogicalAdvancements = aAdvancements;
    }

    geometry::RealRectangle2D SAL_CALL TextLayout::queryTextBounds(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        if( !mpOutDevProvider )
            return geometry::RealRectangle2D();

        OutputDevice& rOutDev = mpOutDevProvider->getOutDev();

        VirtualDevice aVDev( rOutDev );
        aVDev.SetFont( mpFont->getVCLFont() );

        // need metrics for Y offset, the XCanvas always renders
        // relative to baseline
        const ::FontMetric& aMetric( aVDev.GetFontMetric() );

        setupLayoutMode( aVDev, mnTextDirection );

        const sal_Int32 nAboveBaseline( -aMetric.GetIntLeading() - aMetric.GetAscent() );
        const sal_Int32 nBelowBaseline( aMetric.GetDescent() );

        if( maLogicalAdvancements.getLength() )
        {
            return geometry::RealRectangle2D( 0, nAboveBaseline,
                                              maLogicalAdvancements[ maLogicalAdvancements.getLength()-1 ],
                                              nBelowBaseline );
        }
        else
        {
            return geometry::RealRectangle2D( 0, nAboveBaseline,
                                              aVDev.GetTextWidth(
                                                  maText.Text,
                                                  ::canvas::tools::numeric_cast<USHORT>(maText.StartPosition),
                                                  ::canvas::tools::numeric_cast<USHORT>(maText.Length) ),
                                              nBelowBaseline );
        }
    }

    double SAL_CALL TextLayout::justify( double nSize ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)nSize;

        // TODO(F1)
        return 0.0;
    }

    double SAL_CALL TextLayout::combinedJustify( const uno::Sequence< uno::Reference< rendering::XTextLayout > >& aNextLayouts,
                                                 double                                                           nSize ) throw (lang::IllegalArgumentException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)aNextLayouts;
        (void)nSize;

        // TODO(F1)
        return 0.0;
    }

    rendering::TextHit SAL_CALL TextLayout::getTextHit( const geometry::RealPoint2D& aHitPoint ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)aHitPoint;

        // TODO(F1)
        return rendering::TextHit();
    }

    rendering::Caret SAL_CALL TextLayout::getCaret( sal_Int32 nInsertionIndex, sal_Bool bExcludeLigatures ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)nInsertionIndex;
        (void)bExcludeLigatures;

        // TODO(F1)
        return rendering::Caret();
    }

    sal_Int32 SAL_CALL TextLayout::getNextInsertionIndex( sal_Int32 nStartIndex, sal_Int32 nCaretAdvancement, sal_Bool bExcludeLigatures ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)nStartIndex;
        (void)nCaretAdvancement;
        (void)bExcludeLigatures;

        // TODO(F1)
        return 0;
    }

    uno::Reference< rendering::XPolyPolygon2D > SAL_CALL TextLayout::queryVisualHighlighting( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)nStartIndex;
        (void)nEndIndex;

        // TODO(F1)
        return uno::Reference< rendering::XPolyPolygon2D >();
    }

    uno::Reference< rendering::XPolyPolygon2D > SAL_CALL TextLayout::queryLogicalHighlighting( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        (void)nStartIndex;
        (void)nEndIndex;

        // TODO(F1)
        return uno::Reference< rendering::XPolyPolygon2D >();
    }

    double SAL_CALL TextLayout::getBaselineOffset(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        // TODO(F1)
        return 0.0;
    }

    sal_Int8 SAL_CALL TextLayout::getMainTextDirection(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        return mnTextDirection;
    }

    uno::Reference< rendering::XCanvasFont > SAL_CALL TextLayout::getFont(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        return mpFont.getRef();
    }

    rendering::StringContext SAL_CALL TextLayout::getText(  ) throw (uno::RuntimeException)
    {
        tools::LocalGuard aGuard;

        return maText;
    }

    bool TextLayout::draw( OutputDevice&                 rOutDev,
                           const Point&                  rOutpos,
                           const rendering::ViewState&   viewState,
                           const rendering::RenderState& renderState ) const
    {
        tools::LocalGuard aGuard;

        setupLayoutMode( rOutDev, mnTextDirection );

        if( maLogicalAdvancements.getLength() )
        {
            // TODO(P2): cache that
            ::boost::scoped_array< sal_Int32 > aOffsets(new sal_Int32[maLogicalAdvancements.getLength()]);
            setupTextOffsets( aOffsets.get(), maLogicalAdvancements, viewState, renderState );

            // TODO(F3): ensure correct length and termination for DX
            // array (last entry _must_ contain the overall width)

            rOutDev.DrawTextArray( rOutpos,
                                   maText.Text,
                                   aOffsets.get(),
                                   ::canvas::tools::numeric_cast<USHORT>(maText.StartPosition),
                                   ::canvas::tools::numeric_cast<USHORT>(maText.Length) );
        }
        else
        {
            rOutDev.DrawText( rOutpos,
                              maText.Text,
                              ::canvas::tools::numeric_cast<USHORT>(maText.StartPosition),
                              ::canvas::tools::numeric_cast<USHORT>(maText.Length) );
        }

        return true;
    }

    namespace
    {
        class OffsetTransformer
        {
        public:
            OffsetTransformer( const ::basegfx::B2DHomMatrix& rMat ) :
                maMatrix( rMat )
            {
            }

            sal_Int32 operator()( const double& rOffset )
            {
                // This is an optimization of the normal rMat*[x,0]
                // transformation of the advancement vector (in x
                // direction), followed by a length calculation of the
                // resulting vector: advancement' =
                // ||rMat*[x,0]||. Since advancements are vectors, we
                // can ignore translational components, thus if [x,0],
                // it follows that rMat*[x,0]=[x',0] holds. Thus, we
                // just have to calc the transformation of the x
                // component.

                // TODO(F2): Handle non-horizontal advancements!
                return ::basegfx::fround( hypot(maMatrix.get(0,0)*rOffset,
                                                maMatrix.get(1,0)*rOffset) );
            }

        private:
            ::basegfx::B2DHomMatrix maMatrix;
        };
    }

    void TextLayout::setupTextOffsets( sal_Int32*                       outputOffsets,
                                       const uno::Sequence< double >&   inputOffsets,
                                       const rendering::ViewState&      viewState,
                                       const rendering::RenderState&    renderState     ) const
    {
        ENSURE_OR_THROW( outputOffsets!=NULL,
                          "TextLayout::setupTextOffsets offsets NULL" );

        ::basegfx::B2DHomMatrix aMatrix;

        ::canvas::tools::mergeViewAndRenderTransform(aMatrix,
                                                     viewState,
                                                     renderState);

        // fill integer offsets
        ::std::transform( const_cast< uno::Sequence< double >& >(inputOffsets).getConstArray(),
                          const_cast< uno::Sequence< double >& >(inputOffsets).getConstArray()+inputOffsets.getLength(),
                          outputOffsets,
                          OffsetTransformer( aMatrix ) );
    }

#define IMPLEMENTATION_NAME "VCLCanvas::TextLayout"
#define SERVICE_NAME "com.sun.star.rendering.TextLayout"

    ::rtl::OUString SAL_CALL TextLayout::getImplementationName() throw( uno::RuntimeException )
    {
        return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
    }

    sal_Bool SAL_CALL TextLayout::supportsService( const ::rtl::OUString& ServiceName ) throw( uno::RuntimeException )
    {
        return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) );
    }

    uno::Sequence< ::rtl::OUString > SAL_CALL TextLayout::getSupportedServiceNames()  throw( uno::RuntimeException )
    {
        uno::Sequence< ::rtl::OUString > aRet(1);
        aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );

        return aRet;
    }
}
<|endoftext|>


<commit_before>/*
Copyright 2015 University of Auckland

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "libcellml/units.h"

#include <map>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

#include "libcellml/import.h"

namespace libcellml {

/**
 * @brief Map PREFIXES to their string forms.
 * An internal map used to convert a PREFIXES into its string form.
 */
std::map<PREFIXES, std::string> prefixToString =
{
    {PREFIX_ATTO, "atto"},
    {PREFIX_CENTI, "centi"},
    {PREFIX_DECA, "deca"},
    {PREFIX_DECI, "deci"},
    {PREFIX_EXA, "exa"},
    {PREFIX_FEMTO, "femto"},
    {PREFIX_GIGA, "giga"},
    {PREFIX_HECTO, "hecto"},
    {PREFIX_KILO, "kilo"},
    {PREFIX_MEGA, "mega"},
    {PREFIX_MICRO, "micro"},
    {PREFIX_MILLI, "milli"},
    {PREFIX_NANO, "nano"},
    {PREFIX_PETA, "peta"},
    {PREFIX_PICO, "pico"},
    {PREFIX_TERA, "tera"},
    {PREFIX_YOCTO, "yocto"},
    {PREFIX_YOTTA, "yotta"},
    {PREFIX_ZEPTO, "zepto"},
    {PREFIX_ZETTA, "zetta"}
};

/**
 * @brief The Unit struct.
 * An internal structure to capture a unit definition.  The
 * prefix can be expressed using either an integer or an enum.
 * The enum structure member is given preference if both are set.
 */
struct Unit
{
    std::string mName; /**< Name for the unit.*/
    std::string mPrefix; /**< String expression of the prefix for the unit.*/
    std::string mExponent; /**< Exponent for the unit.*/
    std::string mMultiplier; /**< Multiplier for the unit.*/
    std::string mOffset; /**< Offset for the unit.*/
};

/**
 * @brief The Units::UnitsImpl struct.
 * The private implementation for the Units class.
 */
struct Units::UnitsImpl
{
    bool mBaseUnit = false; /**< Flag to determine if this Units is a base unit or not.*/
    std::vector<Unit> mUnits; /**< A vector of unit defined for this Units.*/
};

Units::Units()
    : mPimpl(new UnitsImpl())
{
}

Units::~Units()
{
    delete mPimpl;
}

Units::Units(const Units& rhs)
    : ImportedEntity(rhs)
    , mPimpl(new UnitsImpl())
{
    mPimpl->mBaseUnit = rhs.mPimpl->mBaseUnit;
    mPimpl->mUnits = rhs.mPimpl->mUnits;
}

Units::Units(Units &&rhs)
    : ImportedEntity(std::move(rhs))
    , mPimpl(rhs.mPimpl)
{
    rhs.mPimpl = nullptr;
}

Units& Units::operator=(Units e)
{
    ImportedEntity::operator= (e);
    e.swap(*this);
    return *this;
}

void Units::swap(Units &rhs)
{
    std::swap(this->mPimpl, rhs.mPimpl);
}

std::string Units::doSerialisation(FORMATS format) const
{
    std::string repr = "";
    if (format == FORMAT_XML) {
        if (getName().length()) {
            if (isImport()) {
                repr += "<import xlink:href=\"" + getImport()->getSource() + "\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
                        "<units units_ref=\"" + getImportReference() + "\" name=\"" + getName() + "\"/>"
                        "</import>";
            } else {
                repr += "<units name=\"" + getName() + "\"";
                if (isBaseUnit()) {
                    repr += " base_unit=\"yes\"";
                    repr += "/>";
                } else {
                    repr += ">";
                    for (std::vector<Unit>::size_type i = 0; i != mPimpl->mUnits.size(); ++i) {
                        repr += "<unit";
                        Unit u = mPimpl->mUnits[i];
                        if (u.mExponent.length()) {
                            repr += " exponent=\"" + u.mExponent + "\"";
                        }
                        if (u.mMultiplier.length()) {
                            repr += " multiplier=\"" + u.mMultiplier + "\"";
                        }
                        if (u.mOffset.length()) {
                            repr += " offset=\"" + u.mOffset + "\"";
                        }
                        if (u.mPrefix.length()) {
                            repr += " prefix=\"" + u.mPrefix + "\"";
                        }
                        repr += " units=\"" + u.mName + "\"";
                        repr += "/>";
                    }
                    repr += "</units>";
                }
            }
        }
    }

    return repr;
}

bool Units::isBaseUnit() const
{
    return mPimpl->mBaseUnit;
}

void Units::setBaseUnit(bool state)
{
    mPimpl->mBaseUnit = state;
}

void Units::addUnit(const std::string &name, const std::string &prefix, double exponent,
             double multiplier, double offset)
{
    Unit u;
    u.mName = name;
    // Allow all nonzero user-specified prefixes
    try
    {
        double prefixDouble = std::stod(prefix);
        if (prefixDouble != 0.0) {
            u.mPrefix = prefix;
        }
    } catch(...) {
        u.mPrefix = prefix;
    }
    if (exponent != 1.0) {
        std::ostringstream strs;
        strs << exponent;
        u.mExponent = strs.str();
    }
    if (multiplier != 1.0) {
        std::ostringstream strs;
        strs << multiplier;
        u.mMultiplier = strs.str();
    }
    if (offset != 0.0) {
        std::ostringstream strs;
        strs << offset;
        u.mOffset = strs.str();
    }
    mPimpl->mUnits.push_back(u);
}

void Units::addUnit(const std::string &name, PREFIXES prefix, double exponent,
             double multiplier, double offset)
{
    auto search = prefixToString.find(prefix);
    const std::string prefixString = search->second;
    addUnit(name, prefixString, exponent, multiplier, offset);
}

void Units::addUnit(const std::string &name, double prefix, double exponent,
             double multiplier, double offset)
{
    std::ostringstream strs;
    strs << prefix;
    const std::string prefixString = strs.str();
    addUnit(name, prefixString, exponent, multiplier, offset);
}

void Units::addUnit(const std::string &name, double exponent)
{
    addUnit(name, 0.0, exponent, 1.0, 0.0);
}

void Units::addUnit(const std::string &name)
{
    addUnit(name, 0.0, 1.0, 1.0, 0.0);

}

void Units::setSourceUnits(const ImportPtr &imp, const std::string &name)
{
    setImport(imp);
    setImportReference(name);
}

}
<commit_msg>remove unnecessary includes<commit_after>/*
Copyright 2015 University of Auckland

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "libcellml/units.h"

#include <map>
#include <sstream>
#include <vector>

#include "libcellml/import.h"

namespace libcellml {

/**
 * @brief Map PREFIXES to their string forms.
 * An internal map used to convert a PREFIXES into its string form.
 */
std::map<PREFIXES, std::string> prefixToString =
{
    {PREFIX_ATTO, "atto"},
    {PREFIX_CENTI, "centi"},
    {PREFIX_DECA, "deca"},
    {PREFIX_DECI, "deci"},
    {PREFIX_EXA, "exa"},
    {PREFIX_FEMTO, "femto"},
    {PREFIX_GIGA, "giga"},
    {PREFIX_HECTO, "hecto"},
    {PREFIX_KILO, "kilo"},
    {PREFIX_MEGA, "mega"},
    {PREFIX_MICRO, "micro"},
    {PREFIX_MILLI, "milli"},
    {PREFIX_NANO, "nano"},
    {PREFIX_PETA, "peta"},
    {PREFIX_PICO, "pico"},
    {PREFIX_TERA, "tera"},
    {PREFIX_YOCTO, "yocto"},
    {PREFIX_YOTTA, "yotta"},
    {PREFIX_ZEPTO, "zepto"},
    {PREFIX_ZETTA, "zetta"}
};

/**
 * @brief The Unit struct.
 * An internal structure to capture a unit definition.  The
 * prefix can be expressed using either an integer or an enum.
 * The enum structure member is given preference if both are set.
 */
struct Unit
{
    std::string mName; /**< Name for the unit.*/
    std::string mPrefix; /**< String expression of the prefix for the unit.*/
    std::string mExponent; /**< Exponent for the unit.*/
    std::string mMultiplier; /**< Multiplier for the unit.*/
    std::string mOffset; /**< Offset for the unit.*/
};

/**
 * @brief The Units::UnitsImpl struct.
 * The private implementation for the Units class.
 */
struct Units::UnitsImpl
{
    bool mBaseUnit = false; /**< Flag to determine if this Units is a base unit or not.*/
    std::vector<Unit> mUnits; /**< A vector of unit defined for this Units.*/
};

Units::Units()
    : mPimpl(new UnitsImpl())
{
}

Units::~Units()
{
    delete mPimpl;
}

Units::Units(const Units& rhs)
    : ImportedEntity(rhs)
    , mPimpl(new UnitsImpl())
{
    mPimpl->mBaseUnit = rhs.mPimpl->mBaseUnit;
    mPimpl->mUnits = rhs.mPimpl->mUnits;
}

Units::Units(Units &&rhs)
    : ImportedEntity(std::move(rhs))
    , mPimpl(rhs.mPimpl)
{
    rhs.mPimpl = nullptr;
}

Units& Units::operator=(Units e)
{
    ImportedEntity::operator= (e);
    e.swap(*this);
    return *this;
}

void Units::swap(Units &rhs)
{
    std::swap(this->mPimpl, rhs.mPimpl);
}

std::string Units::doSerialisation(FORMATS format) const
{
    std::string repr = "";
    if (format == FORMAT_XML) {
        if (getName().length()) {
            if (isImport()) {
                repr += "<import xlink:href=\"" + getImport()->getSource() + "\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
                        "<units units_ref=\"" + getImportReference() + "\" name=\"" + getName() + "\"/>"
                        "</import>";
            } else {
                repr += "<units name=\"" + getName() + "\"";
                if (isBaseUnit()) {
                    repr += " base_unit=\"yes\"";
                    repr += "/>";
                } else {
                    repr += ">";
                    for (std::vector<Unit>::size_type i = 0; i != mPimpl->mUnits.size(); ++i) {
                        repr += "<unit";
                        Unit u = mPimpl->mUnits[i];
                        if (u.mExponent.length()) {
                            repr += " exponent=\"" + u.mExponent + "\"";
                        }
                        if (u.mMultiplier.length()) {
                            repr += " multiplier=\"" + u.mMultiplier + "\"";
                        }
                        if (u.mOffset.length()) {
                            repr += " offset=\"" + u.mOffset + "\"";
                        }
                        if (u.mPrefix.length()) {
                            repr += " prefix=\"" + u.mPrefix + "\"";
                        }
                        repr += " units=\"" + u.mName + "\"";
                        repr += "/>";
                    }
                    repr += "</units>";
                }
            }
        }
    }

    return repr;
}

bool Units::isBaseUnit() const
{
    return mPimpl->mBaseUnit;
}

void Units::setBaseUnit(bool state)
{
    mPimpl->mBaseUnit = state;
}

void Units::addUnit(const std::string &name, const std::string &prefix, double exponent,
             double multiplier, double offset)
{
    Unit u;
    u.mName = name;
    // Allow all nonzero user-specified prefixes
    try
    {
        double prefixDouble = std::stod(prefix);
        if (prefixDouble != 0.0) {
            u.mPrefix = prefix;
        }
    } catch(...) {
        u.mPrefix = prefix;
    }
    if (exponent != 1.0) {
        std::ostringstream strs;
        strs << exponent;
        u.mExponent = strs.str();
    }
    if (multiplier != 1.0) {
        std::ostringstream strs;
        strs << multiplier;
        u.mMultiplier = strs.str();
    }
    if (offset != 0.0) {
        std::ostringstream strs;
        strs << offset;
        u.mOffset = strs.str();
    }
    mPimpl->mUnits.push_back(u);
}

void Units::addUnit(const std::string &name, PREFIXES prefix, double exponent,
             double multiplier, double offset)
{
    auto search = prefixToString.find(prefix);
    const std::string prefixString = search->second;
    addUnit(name, prefixString, exponent, multiplier, offset);
}

void Units::addUnit(const std::string &name, double prefix, double exponent,
             double multiplier, double offset)
{
    std::ostringstream strs;
    strs << prefix;
    const std::string prefixString = strs.str();
    addUnit(name, prefixString, exponent, multiplier, offset);
}

void Units::addUnit(const std::string &name, double exponent)
{
    addUnit(name, 0.0, exponent, 1.0, 0.0);
}

void Units::addUnit(const std::string &name)
{
    addUnit(name, 0.0, 1.0, 1.0, 0.0);

}

void Units::setSourceUnits(const ImportPtr &imp, const std::string &name)
{
    setImport(imp);
    setImportReference(name);
}

}
<|endoftext|>


<commit_before><commit_msg>Don't render with mp2DRenderer when we have 3D charts<commit_after><|endoftext|>


<commit_before>#include "ee/cocos-coroutine/Delay.hpp"

#include <base/CCDirector.h>
#include <base/CCScheduler.h>

namespace ee {
namespace coroutine {
using Self = Delay;

Self::Delay(float duration)
    : duration_(duration) {
    CC_ASSERT(duration_ >= 0);
}

void Self::await_suspend(std::experimental::coroutine_handle<> handle) {
    if (duration_ == 0) {
        handle.resume();
        return;
    }
    auto director = cocos2d::Director::getInstance();
    auto scheduler = director->getScheduler();
    scheduler->schedule(
        [this, handle](float delta) mutable {
            ready_ = true;
            handle.resume();
        },
        this, 0, 0, duration_, false, "await_suspend");
}

bool Self::await_ready() {
    if (duration_ == 0) {
        return true;
    }
    return ready_;
}

void Self::await_resume() {}
} // namespace coroutine
} // namespace ee
<commit_msg>Fix include.<commit_after>#include "ee/cocos_coroutine/Delay.hpp"

#include <base/CCDirector.h>
#include <base/CCScheduler.h>

namespace ee {
namespace coroutine {
using Self = Delay;

Self::Delay(float duration)
    : duration_(duration) {
    CC_ASSERT(duration_ >= 0);
}

void Self::await_suspend(std::experimental::coroutine_handle<> handle) {
    if (duration_ == 0) {
        handle.resume();
        return;
    }
    auto director = cocos2d::Director::getInstance();
    auto scheduler = director->getScheduler();
    scheduler->schedule(
        [this, handle](float delta) mutable {
            ready_ = true;
            handle.resume();
        },
        this, 0, 0, duration_, false, "await_suspend");
}

bool Self::await_ready() {
    if (duration_ == 0) {
        return true;
    }
    return ready_;
}

void Self::await_resume() {}
} // namespace coroutine
} // namespace ee
<|endoftext|>