<commit_before>/****************************************************************************
 **
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 **
 ** This file is part of the QxtCore module of the Qxt library.
 **
 ** This library is free software; you can redistribute it and/or modify it
 ** under the terms of the Common Public License, version 1.0, as published
 ** by IBM, and/or under the terms of the GNU Lesser General Public License,
 ** version 2.1, as published by the Free Software Foundation.
 **
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 ** FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** You should have received a copy of the CPL and the LGPL along with this
 ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
 ** included with the source distribution for more information.
 ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
 **
 ** <http://libqxt.org>  <foundation@libqxt.org>
 **
 ****************************************************************************/
#include "qxtmodelserializer.h"
#include <QAbstractItemModel>
#include <QDataStream>

/*!
    \class QxtModelSerializer QxtModelSerializer
    \inmodule QxtCore
    \brief Provides serialization of QAbstractItemModel
 */

struct QxtModelItem
{
    QMap<int, QVariant> itemData;
    int rowCount;
    int columnCount;
};

inline QDataStream& operator<<(QDataStream& out, const QxtModelItem& item)
{
    out << item.itemData;
    out << item.rowCount;
    out << item.columnCount;
    return out;
}

inline QDataStream& operator>>(QDataStream& in, QxtModelItem& item)
{
    in >> item.itemData;
    in >> item.rowCount;
    in >> item.columnCount;
    return in;
}

class QxtModelSerializerPrivate : public QxtPrivate<QxtModelSerializer>
{
public:
    QxtModelSerializerPrivate() : model(0) { }

    void save(QDataStream& stream, const QModelIndex& index) const;
    bool restore(QDataStream& stream, const QModelIndex& index);
    void print(const QByteArray& data) const;

    QAbstractItemModel* model;
};

void QxtModelSerializerPrivate::save(QDataStream& stream, const QModelIndex& index) const
{
    QxtModelItem item;
    item.itemData = model->itemData(index);
    item.rowCount = model->rowCount(index);
    item.columnCount = model->columnCount(index);
    stream << item;
    for (int r = 0; r < item.rowCount; ++r)
        for (int c = 0; c < item.columnCount; ++c)
            save(stream, model->index(r, c, index));
}

bool QxtModelSerializerPrivate::restore(QDataStream& stream, const QModelIndex& index)
{
    QxtModelItem item;
    stream >> item;

    if (index.isValid())
        model->setItemData(index, item.itemData);
    if (item.rowCount > 0)
        model->insertRows(0, item.rowCount, index);
    if (item.columnCount > 0)
        model->insertColumns(0, item.columnCount, index);

    for (int r = 0; r < item.rowCount; ++r)
    {
        for (int c = 0; c < item.columnCount; ++c)
            restore(stream, model->index(r, c, index));
    }
    return stream.status() == QDataStream::Ok;
}

void QxtModelSerializerPrivate::print(const QByteArray& data) const
{
    QDataStream stream(data);
    while (!stream.atEnd())
    {
        QxtModelItem item;
        stream >> item;
    }
}

QxtModelSerializer::QxtModelSerializer(QAbstractItemModel* model)
{
    qxt_d().model = model;
}

QxtModelSerializer::~QxtModelSerializer()
{
}

QAbstractItemModel* QxtModelSerializer::model() const
{
    return qxt_d().model;
}

void QxtModelSerializer::setModel(QAbstractItemModel* model)
{
    qxt_d().model = model;
}

QByteArray QxtModelSerializer::saveModel(const QModelIndex& index) const
{
    if (!qxt_d().model)
    {
        qWarning("QxtModelSerializer::saveModel(): model == null");
        return QByteArray();
    }

    QByteArray data;
    QDataStream stream(&data, QIODevice::WriteOnly);
    qxt_d().save(stream, index);
    qxt_d().print(data);
    return data;
}

bool QxtModelSerializer::restoreModel(const QByteArray& data, const QModelIndex& index)
{
    if (!qxt_d().model)
    {
        qWarning("QxtModelSerializer::restoreModel(): model == null");
        return false;
    }

    QDataStream stream(data);
    qxt_d().print(data);
    return qxt_d().restore(stream, index);
}
<commit_msg>Disabled QxtModelSerializer docs temporarily.<commit_after>/****************************************************************************
 **
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 **
 ** This file is part of the QxtCore module of the Qxt library.
 **
 ** This library is free software; you can redistribute it and/or modify it
 ** under the terms of the Common Public License, version 1.0, as published
 ** by IBM, and/or under the terms of the GNU Lesser General Public License,
 ** version 2.1, as published by the Free Software Foundation.
 **
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 ** FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** You should have received a copy of the CPL and the LGPL along with this
 ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
 ** included with the source distribution for more information.
 ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
 **
 ** <http://libqxt.org>  <foundation@libqxt.org>
 **
 ****************************************************************************/
#include "qxtmodelserializer.h"
#include <QAbstractItemModel>
#include <QDataStream>

/*
    \class QxtModelSerializer
    \inmodule QxtCore
    \brief Provides serialization of QAbstractItemModel
 */

struct QxtModelItem
{
    QMap<int, QVariant> itemData;
    int rowCount;
    int columnCount;
};

inline QDataStream& operator<<(QDataStream& out, const QxtModelItem& item)
{
    out << item.itemData;
    out << item.rowCount;
    out << item.columnCount;
    return out;
}

inline QDataStream& operator>>(QDataStream& in, QxtModelItem& item)
{
    in >> item.itemData;
    in >> item.rowCount;
    in >> item.columnCount;
    return in;
}

class QxtModelSerializerPrivate : public QxtPrivate<QxtModelSerializer>
{
public:
    QxtModelSerializerPrivate() : model(0) { }

    void save(QDataStream& stream, const QModelIndex& index) const;
    bool restore(QDataStream& stream, const QModelIndex& index);
    void print(const QByteArray& data) const;

    QAbstractItemModel* model;
};

void QxtModelSerializerPrivate::save(QDataStream& stream, const QModelIndex& index) const
{
    QxtModelItem item;
    item.itemData = model->itemData(index);
    item.rowCount = model->rowCount(index);
    item.columnCount = model->columnCount(index);
    stream << item;
    for (int r = 0; r < item.rowCount; ++r)
        for (int c = 0; c < item.columnCount; ++c)
            save(stream, model->index(r, c, index));
}

bool QxtModelSerializerPrivate::restore(QDataStream& stream, const QModelIndex& index)
{
    QxtModelItem item;
    stream >> item;

    if (index.isValid())
        model->setItemData(index, item.itemData);
    if (item.rowCount > 0)
        model->insertRows(0, item.rowCount, index);
    if (item.columnCount > 0)
        model->insertColumns(0, item.columnCount, index);

    for (int r = 0; r < item.rowCount; ++r)
    {
        for (int c = 0; c < item.columnCount; ++c)
            restore(stream, model->index(r, c, index));
    }
    return stream.status() == QDataStream::Ok;
}

void QxtModelSerializerPrivate::print(const QByteArray& data) const
{
    QDataStream stream(data);
    while (!stream.atEnd())
    {
        QxtModelItem item;
        stream >> item;
    }
}

QxtModelSerializer::QxtModelSerializer(QAbstractItemModel* model)
{
    qxt_d().model = model;
}

QxtModelSerializer::~QxtModelSerializer()
{
}

QAbstractItemModel* QxtModelSerializer::model() const
{
    return qxt_d().model;
}

void QxtModelSerializer::setModel(QAbstractItemModel* model)
{
    qxt_d().model = model;
}

QByteArray QxtModelSerializer::saveModel(const QModelIndex& index) const
{
    if (!qxt_d().model)
    {
        qWarning("QxtModelSerializer::saveModel(): model == null");
        return QByteArray();
    }

    QByteArray data;
    QDataStream stream(&data, QIODevice::WriteOnly);
    qxt_d().save(stream, index);
    qxt_d().print(data);
    return data;
}

bool QxtModelSerializer::restoreModel(const QByteArray& data, const QModelIndex& index)
{
    if (!qxt_d().model)
    {
        qWarning("QxtModelSerializer::restoreModel(): model == null");
        return false;
    }

    QDataStream stream(data);
    qxt_d().print(data);
    return qxt_d().restore(stream, index);
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QGraphicsSceneContextMenuEvent>
#include <QSettings>
#include "mbuttongroup.h"
#include "mbutton.h"
#include "mbutton_p.h"
#include "mtheme.h"

#include "mwidgetcreator.h"
M_REGISTER_WIDGET(MButton)

const MTheme::ViewType MButton::toggleType      = "toggle";
const MTheme::ViewType MButton::checkboxType    = "checkbox";
const MTheme::ViewType MButton::iconType        = "icon";
const MTheme::ViewType MButton::switchType      = "switch";
const MTheme::ViewType MButton::groupType       = "group";

MButtonPrivate::MButtonPrivate()
    : MWidgetControllerPrivate(),
    buttonGroup(0)
{
}

MButtonPrivate::~MButtonPrivate()
{
}

void MButtonPrivate::init()
{
}

void MButtonPrivate::init(const QString &newIconID, const QString &newText)
{
    Q_Q(MButton);
    init();

    q->setText(newText);
    q->setIconID(newIconID);
}

MButton::MButton(MButtonPrivate *dd, MButtonModel *model, QGraphicsItem *parent)
    : MWidgetController(dd, model, parent)
{
    Q_D(MButton);

    d->init();
}

MButton::MButton(QGraphicsItem *parent, MButtonModel *model)
    : MWidgetController(new MButtonPrivate, model == NULL ? new MButtonModel : model, parent)
{
    Q_D(MButton);

    d->init();
}

MButton::MButton(const QString &text, QGraphicsItem *parent, MButtonModel *model)
    : MWidgetController(new MButtonPrivate, model == NULL ? new MButtonModel : model, parent)
{
    Q_D(MButton);

    d->init(QString(), text);
}

MButton::MButton(const QString &iconID, const QString &text, QGraphicsItem *parent, MButtonModel *model)
    : MWidgetController(new MButtonPrivate, model == NULL ? new MButtonModel : model, parent)
{
    Q_D(MButton);

    d->init(iconID, text);
}

MButton::~MButton()
{
    Q_D(MButton);

    if (d->buttonGroup) {
        d->buttonGroup->removeButton(this);
    }
}

void MButton::setIconID(const QString &iconID)
{
    model()->setIconID(iconID);
}

QString MButton::iconID() const
{
    return model()->iconID();
}

void MButton::setToggledIconID(const QString &toggledIconID)
{
    model()->setToggledIconID(toggledIconID);
}

QString MButton::toggledIconID() const
{
    return model()->toggledIconID();
}

void MButton::setIcon(const QIcon &icon)
{
    model()->setIcon(icon);
}

QIcon MButton::icon() const
{
    return model()->icon();
}

void MButton::setText(const QString &text)
{
    model()->setText(text);
}

QString MButton::text() const
{
    return model()->text();
}

bool MButton::isTextVisible() const
{
    return model()->textVisible();
}

void MButton::setTextVisible(bool textVisible)
{
    model()->setTextVisible(textVisible);
}

bool MButton::isIconVisible() const
{
    return model()->iconVisible();
}

void MButton::setIconVisible(bool iconVisible)
{
    model()->setIconVisible(iconVisible);
}

bool MButton::isCheckable() const
{
    return model()->checkable();
}

void MButton::setCheckable(bool buttonCheckable)
{
    if (!buttonCheckable && model()->checked())
        model()->setChecked(false);
    model()->setCheckable(buttonCheckable);
}

bool MButton::isChecked() const
{
    return model()->checked();
}

//TODO Remove this when delayed model initialization bug is properly fixed.
static bool toggleEmitted = false;

void MButton::setChecked(bool buttonChecked)
{
    // FIXME: these checks could be done in model side, the group needs moved to model first
    if (isCheckable() && buttonChecked != isChecked()) {

        /* The active button in an exclusive group cannot be deselected */
        if (group() && group()->exclusive() && group()->checkedButton() == this) {
            return;
        }

        //TODO This is here just because of the delayed model initialization, this
        //     call should be removed when the delayed model initialization bug/feature
        //     is properly fixed.
        //
        //     The bug causes invalid functionaliy for buttons inside a buttongroup,
        //     if state of a button(s) is changed before messageloop is run first
        //     time. The updateData() slot does does not get called and toggled
        //     signal is not emitted. Exclusive buttongroup uses the toggled signal
        //     to uncheck buttons.
        bool shouldEmit = (model()->checked() != buttonChecked);
        toggleEmitted = false;

        model()->setChecked(buttonChecked);

        //TODO Remove this when delayed model initialization bug is properly fixed.
        if (shouldEmit && !toggleEmitted)
            emit toggled(model()->checked());
    }
}

bool MButton::isDown() const
{
    return model()->down();
}

void MButton::setDown(bool status)
{
    model()->setDown(status);
}

void MButton::click()
{
    model()->setDown(true);
    model()->setDown(false);
    modelClick();
}

void MButton::toggle()
{
    setChecked(!isChecked());
}

MButtonGroup *MButton::group() const
{
    Q_D(const MButton);
    return d->buttonGroup;
}

void MButton::setGroup(MButtonGroup *group)
{
    Q_D(MButton);

    d->buttonGroup = group;
}

void MButton::setupModel()
{
    MWidgetController::setupModel();

    connect(model(), SIGNAL(clicked()), SLOT(modelClick()));
}

void MButton::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    MWidgetController::contextMenuEvent(event);
    event->accept();
}

void MButton::updateData(const QList<const char *>& modifications)
{
    MWidgetController::updateData(modifications);

    const char *member;
    foreach(member, modifications) {
        if (member == MButtonModel::Checked) {
            emit toggled(model()->checked());

            //TODO Remove this when delayed model initialization bug is properly fixed.
            toggleEmitted = true;
        } else if (member == MButtonModel::Down) {
            if (model()->down())
                emit pressed();
            else
                emit released();
        }
    }
}

void MButton::modelClick()
{
    toggle();
    emit clicked(isChecked());
}

<commit_msg>Changes: The button will ignore the context menu event and propagate it further.<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QGraphicsSceneContextMenuEvent>
#include <QSettings>
#include "mbuttongroup.h"
#include "mbutton.h"
#include "mbutton_p.h"
#include "mtheme.h"

#include "mwidgetcreator.h"
M_REGISTER_WIDGET(MButton)

const MTheme::ViewType MButton::toggleType      = "toggle";
const MTheme::ViewType MButton::checkboxType    = "checkbox";
const MTheme::ViewType MButton::iconType        = "icon";
const MTheme::ViewType MButton::switchType      = "switch";
const MTheme::ViewType MButton::groupType       = "group";

MButtonPrivate::MButtonPrivate()
    : MWidgetControllerPrivate(),
    buttonGroup(0)
{
}

MButtonPrivate::~MButtonPrivate()
{
}

void MButtonPrivate::init()
{
}

void MButtonPrivate::init(const QString &newIconID, const QString &newText)
{
    Q_Q(MButton);
    init();

    q->setText(newText);
    q->setIconID(newIconID);
}

MButton::MButton(MButtonPrivate *dd, MButtonModel *model, QGraphicsItem *parent)
    : MWidgetController(dd, model, parent)
{
    Q_D(MButton);

    d->init();
}

MButton::MButton(QGraphicsItem *parent, MButtonModel *model)
    : MWidgetController(new MButtonPrivate, model == NULL ? new MButtonModel : model, parent)
{
    Q_D(MButton);

    d->init();
}

MButton::MButton(const QString &text, QGraphicsItem *parent, MButtonModel *model)
    : MWidgetController(new MButtonPrivate, model == NULL ? new MButtonModel : model, parent)
{
    Q_D(MButton);

    d->init(QString(), text);
}

MButton::MButton(const QString &iconID, const QString &text, QGraphicsItem *parent, MButtonModel *model)
    : MWidgetController(new MButtonPrivate, model == NULL ? new MButtonModel : model, parent)
{
    Q_D(MButton);

    d->init(iconID, text);
}

MButton::~MButton()
{
    Q_D(MButton);

    if (d->buttonGroup) {
        d->buttonGroup->removeButton(this);
    }
}

void MButton::setIconID(const QString &iconID)
{
    model()->setIconID(iconID);
}

QString MButton::iconID() const
{
    return model()->iconID();
}

void MButton::setToggledIconID(const QString &toggledIconID)
{
    model()->setToggledIconID(toggledIconID);
}

QString MButton::toggledIconID() const
{
    return model()->toggledIconID();
}

void MButton::setIcon(const QIcon &icon)
{
    model()->setIcon(icon);
}

QIcon MButton::icon() const
{
    return model()->icon();
}

void MButton::setText(const QString &text)
{
    model()->setText(text);
}

QString MButton::text() const
{
    return model()->text();
}

bool MButton::isTextVisible() const
{
    return model()->textVisible();
}

void MButton::setTextVisible(bool textVisible)
{
    model()->setTextVisible(textVisible);
}

bool MButton::isIconVisible() const
{
    return model()->iconVisible();
}

void MButton::setIconVisible(bool iconVisible)
{
    model()->setIconVisible(iconVisible);
}

bool MButton::isCheckable() const
{
    return model()->checkable();
}

void MButton::setCheckable(bool buttonCheckable)
{
    if (!buttonCheckable && model()->checked())
        model()->setChecked(false);
    model()->setCheckable(buttonCheckable);
}

bool MButton::isChecked() const
{
    return model()->checked();
}

//TODO Remove this when delayed model initialization bug is properly fixed.
static bool toggleEmitted = false;

void MButton::setChecked(bool buttonChecked)
{
    // FIXME: these checks could be done in model side, the group needs moved to model first
    if (isCheckable() && buttonChecked != isChecked()) {

        /* The active button in an exclusive group cannot be deselected */
        if (group() && group()->exclusive() && group()->checkedButton() == this) {
            return;
        }

        //TODO This is here just because of the delayed model initialization, this
        //     call should be removed when the delayed model initialization bug/feature
        //     is properly fixed.
        //
        //     The bug causes invalid functionaliy for buttons inside a buttongroup,
        //     if state of a button(s) is changed before messageloop is run first
        //     time. The updateData() slot does does not get called and toggled
        //     signal is not emitted. Exclusive buttongroup uses the toggled signal
        //     to uncheck buttons.
        bool shouldEmit = (model()->checked() != buttonChecked);
        toggleEmitted = false;

        model()->setChecked(buttonChecked);

        //TODO Remove this when delayed model initialization bug is properly fixed.
        if (shouldEmit && !toggleEmitted)
            emit toggled(model()->checked());
    }
}

bool MButton::isDown() const
{
    return model()->down();
}

void MButton::setDown(bool status)
{
    model()->setDown(status);
}

void MButton::click()
{
    model()->setDown(true);
    model()->setDown(false);
    modelClick();
}

void MButton::toggle()
{
    setChecked(!isChecked());
}

MButtonGroup *MButton::group() const
{
    Q_D(const MButton);
    return d->buttonGroup;
}

void MButton::setGroup(MButtonGroup *group)
{
    Q_D(MButton);

    d->buttonGroup = group;
}

void MButton::setupModel()
{
    MWidgetController::setupModel();

    connect(model(), SIGNAL(clicked()), SLOT(modelClick()));
}

void MButton::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    MWidgetController::contextMenuEvent(event);
}

void MButton::updateData(const QList<const char *>& modifications)
{
    MWidgetController::updateData(modifications);

    const char *member;
    foreach(member, modifications) {
        if (member == MButtonModel::Checked) {
            emit toggled(model()->checked());

            //TODO Remove this when delayed model initialization bug is properly fixed.
            toggleEmitted = true;
        } else if (member == MButtonModel::Down) {
            if (model()->down())
                emit pressed();
            else
                emit released();
        }
    }
}

void MButton::modelClick()
{
    toggle();
    emit clicked(isChecked());
}

<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "ppapi/tests/test_mouse_lock.h"

#include "ppapi/cpp/input_event.h"
#include "ppapi/cpp/view.h"
#include "ppapi/tests/testing_instance.h"

REGISTER_TEST_CASE(MouseLock);

TestMouseLock::TestMouseLock(TestingInstance* instance)
    : TestCase(instance),
      MouseLock(instance),
      nested_event_(instance->pp_instance()) {
}

TestMouseLock::~TestMouseLock() {
}

bool TestMouseLock::Init() {
  return CheckTestingInterface();
}

void TestMouseLock::RunTests(const std::string& filter) {
  RUN_TEST(SucceedWhenAllowed, filter);
  RUN_TEST(FailWhenBlocked, filter);
}

void TestMouseLock::DidChangeView(const pp::View& view) {
  position_ = view.GetRect();
}

void TestMouseLock::MouseLockLost() {
  nested_event_.Signal();
}

std::string TestMouseLock::TestSucceedWhenAllowed() {
  // Content settings are configured to allow mouse lock for any site.
  // Please see chrome/test/ppapi/ppapi_interactive_browsertest.cc.
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  SimulateUserGesture();
  callback.WaitForResult(LockMouse(callback));
  ASSERT_EQ(PP_OK, callback.result());

  UnlockMouse();
  // Wait for the MouseLockLost() call.
  nested_event_.Wait();

  PASS();
}

std::string TestMouseLock::TestFailWhenBlocked() {
  // Content settings are configured to block mouse lock for any site.
  // Please see chrome/test/ppapi/ppapi_interactive_browsertest.cc.
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  SimulateUserGesture();
  callback.WaitForResult(LockMouse(callback));
  ASSERT_NE(PP_OK, callback.result());

  PASS();
}

void TestMouseLock::SimulateUserGesture() {
  pp::Point mouse_movement;
  pp::MouseInputEvent input_event(
      instance_,
      PP_INPUTEVENT_TYPE_MOUSEDOWN,
      0,  // time_stamp
      0,  // modifiers
      PP_INPUTEVENT_MOUSEBUTTON_LEFT,
      position_.CenterPoint(),
      1,  // click_count
      mouse_movement);

  testing_interface_->SimulateInputEvent(instance_->pp_instance(),
                                         input_event.pp_resource());
}
<commit_msg>Disable SucceedWhenAllowed due to timeouts.<commit_after>// Copyright (c) 2012 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 "ppapi/tests/test_mouse_lock.h"

#include "ppapi/cpp/input_event.h"
#include "ppapi/cpp/view.h"
#include "ppapi/tests/testing_instance.h"

REGISTER_TEST_CASE(MouseLock);

TestMouseLock::TestMouseLock(TestingInstance* instance)
    : TestCase(instance),
      MouseLock(instance),
      nested_event_(instance->pp_instance()) {
}

TestMouseLock::~TestMouseLock() {
}

bool TestMouseLock::Init() {
  return CheckTestingInterface();
}

void TestMouseLock::RunTests(const std::string& filter) {
  // Disabled due to timeouts: http://crbug.com/136548
  // RUN_TEST(SucceedWhenAllowed, filter);
  RUN_TEST(FailWhenBlocked, filter);
}

void TestMouseLock::DidChangeView(const pp::View& view) {
  position_ = view.GetRect();
}

void TestMouseLock::MouseLockLost() {
  nested_event_.Signal();
}

std::string TestMouseLock::TestSucceedWhenAllowed() {
  // Content settings are configured to allow mouse lock for any site.
  // Please see chrome/test/ppapi/ppapi_interactive_browsertest.cc.
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  SimulateUserGesture();
  callback.WaitForResult(LockMouse(callback));
  ASSERT_EQ(PP_OK, callback.result());

  UnlockMouse();
  // Wait for the MouseLockLost() call.
  nested_event_.Wait();

  PASS();
}

std::string TestMouseLock::TestFailWhenBlocked() {
  // Content settings are configured to block mouse lock for any site.
  // Please see chrome/test/ppapi/ppapi_interactive_browsertest.cc.
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  SimulateUserGesture();
  callback.WaitForResult(LockMouse(callback));
  ASSERT_NE(PP_OK, callback.result());

  PASS();
}

void TestMouseLock::SimulateUserGesture() {
  pp::Point mouse_movement;
  pp::MouseInputEvent input_event(
      instance_,
      PP_INPUTEVENT_TYPE_MOUSEDOWN,
      0,  // time_stamp
      0,  // modifiers
      PP_INPUTEVENT_MOUSEBUTTON_LEFT,
      position_.CenterPoint(),
      1,  // click_count
      mouse_movement);

  testing_interface_->SimulateInputEvent(instance_->pp_instance(),
                                         input_event.pp_resource());
}
<|endoftext|>


<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <cassert>

#include <algorithm>
#include <iostream>
#include <limits>
#include <ostream>

#include <GL/glew.h>

#include <osg/io_utils>
#include <osg/Material>
#include <osg/MatrixTransform>
#include <osg/StateSet>
#include <osg/TriangleFunctor>

#include <cover/coVRConfig.h>
#include <cover/coVRPluginSupport.h>
#include <cover/VRViewer.h>

#include <visionaray/detail/aligned_vector.h>
#include <visionaray/math/math.h>
#include <visionaray/bvh.h>
#include <visionaray/kernels.h>
#include <visionaray/point_light.h>
#include <visionaray/render_target.h>
#include <visionaray/scheduler.h>

#include "visionaray_plugin.h"

namespace visionaray { namespace cover {

//-------------------------------------------------------------------------------------------------
// Type definitions
//

using triangle_type     = basic_triangle<3, float>;
using triangle_list     = aligned_vector<triangle_type>;
using normal_list       = aligned_vector<vec3>;
using material_list     = aligned_vector<phong<float>>;

using host_ray_type     = basic_ray<simd::float4>;
using host_bvh_type     = bvh<triangle_type>;
using host_sched_type   = tiled_sched<host_ray_type>;

//-------------------------------------------------------------------------------------------------
// Functor that stores triangles from osg::Drawable
//

class store_triangle
{
public:

    store_triangle() : triangles_(nullptr) {}

    void init(triangle_list& tris, normal_list& norms, unsigned geom_id)
    {
        triangles_  = &tris;
        normals_    = &norms;
        geom_id_    = geom_id;
    }

    void operator()(osg::Vec3 const& v1, osg::Vec3 const& v2, osg::Vec3 const& v3, bool) const
    {
        assert( triangles_ && normals_ );

        triangle_type tri;
        tri.prim_id = static_cast<unsigned>(triangles_->size());
        tri.geom_id = geom_id_;
        tri.v1 = vec3(v1.x(), v1.y(), v1.z());
        tri.e1 = vec3(v2.x(), v2.y(), v2.z()) - tri.v1;
        tri.e2 = vec3(v3.x(), v3.y(), v3.z()) - tri.v1;
        triangles_->push_back(tri);

        normals_->push_back( normalize(cross(tri.e1, tri.e2)) );

        assert( triangles_->size() == normals_->size() );
    }

private:

    // Store pointers because osg::TriangleFunctor is shitty..
    triangle_list*  triangles_;
    normal_list*    normals_;
    unsigned        geom_id_;

};

//-------------------------------------------------------------------------------------------------
// Visitor to acquire scene data
//

class get_scene_visitor : public osg::NodeVisitor
{
public:

    using base_type = osg::NodeVisitor;
    using base_type::apply;

    get_scene_visitor(triangle_list& tris, normal_list& norms, material_list& mats, TraversalMode tm)
        : base_type(tm)
        , triangles_(tris)
        , normals_(norms)
        , materials_(mats)
    {
    }

    void apply(osg::Geode& geode)
    {
        for (size_t i = 0; i < geode.getNumDrawables(); ++i)
        {
            auto drawable = geode.getDrawable(i);
            if (drawable)
            {
                auto set = drawable->getOrCreateStateSet();
                auto attr = set->getAttribute(osg::StateAttribute::MATERIAL);
                auto mat = dynamic_cast<osg::Material*>(attr);

                if (mat)
                {
                    auto cd = mat->getDiffuse(osg::Material::Face::FRONT);
                    auto cs = mat->getSpecular(osg::Material::Face::FRONT);

                    phong<float> vsnray_mat;
                    vsnray_mat.set_cd( vec3(cd.x(), cd.y(), cd.z()) );
                    vsnray_mat.set_kd( 1.0f );
                    vsnray_mat.set_ks( cs.x() ); // TODO: e.g. luminance?
                    vsnray_mat.set_specular_exp( mat->getShininess(osg::Material::Face::FRONT) );
                    materials_.push_back(vsnray_mat);
                }

                assert( static_cast<material_list::size_type>(static_cast<unsigned>(materials.size()) == materials.size()) );

                osg::TriangleFunctor<store_triangle> tf;
                tf.init( triangles_, normals_, materials_.size() == 0 ? 0 : static_cast<unsigned>(materials_.size() - 1) );
                drawable->accept(tf);
            }
        }

        base_type::traverse(geode);
    }

private:

    triangle_list&  triangles_;
    normal_list&    normals_;
    material_list&  materials_;

};

//-------------------------------------------------------------------------------------------------
// Private implementation
//

struct Visionaray::impl
{
    impl()
    {
    }

    triangle_list                       triangles;
    normal_list                         normals;
    material_list                       materials;
    host_bvh_type                       host_bvh;
    host_sched_type                     host_sched;
    cpu_buffer_rt                       host_rt;

    recti                               viewport;

    osg::ref_ptr<osg::Geode>            geode;
};

Visionaray::Visionaray()
    : impl_(new impl)
{
    setSupportsDisplayList(false);
}

Visionaray::Visionaray(Visionaray const& rhs, osg::CopyOp const& op)
    : Drawable(rhs, op)
    , impl_(new impl)
{
    setSupportsDisplayList(false);
}

Visionaray::~Visionaray()
{
    opencover::cover->getObjectsRoot()->removeChild(impl_->geode);
}

bool Visionaray::init()
{
    using namespace osg;

    opencover::VRViewer::instance()->culling(false);

    std::cout << "Init Visionaray Plugin!!" << std::endl;

    ref_ptr<osg::StateSet> state = new osg::StateSet();
    state->setGlobalDefaults();

    impl_->geode = new osg::Geode;
    impl_->geode->setName("Visionaray");
    impl_->geode->setStateSet(state);
    impl_->geode->addDrawable(this);

    opencover::cover->getScene()->addChild(impl_->geode);

    return true;
}

void Visionaray::preFrame()
{
}

void Visionaray::expandBoundingSphere(osg::BoundingSphere &bs)
{
    aabb bounds( vec3(std::numeric_limits<float>::max()), -vec3(std::numeric_limits<float>::max()) );
    for (auto const& tri : impl_->triangles)
    {
        auto v1 = tri.v1;
        auto v2 = tri.v1 + tri.e1;
        auto v3 = tri.v1 + tri.e2;

        bounds = combine(bounds, aabb(v1, v1));
        bounds = combine(bounds, aabb(v2, v2));
        bounds = combine(bounds, aabb(v3, v3));
    }

    auto c = bounds.center();
    osg::BoundingSphere::vec_type center(c.x, c.y, c.z);
    osg::BoundingSphere::value_type radius = length( c - bounds.min );
    bs.set(center, radius);
}

void Visionaray::drawImplementation(osg::RenderInfo&) const
{
    // TODO?

    static bool glewed = false;

    if (!glewed)
    {
        glewed = glewInit() == GLEW_OK;
    }

    // Scene data

    if (impl_->triangles.size() == 0)
    {
        // TODO: no dynamic scenes for now :(
        get_scene_visitor visitor(impl_->triangles, impl_->normals, impl_->materials,
            osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
        visitor.apply(*opencover::cover->getObjectsRoot());

        if (impl_->triangles.size() == 0)
        {
            return;
        }

        if (impl_->materials.size() == 0)
        {
            phong<float> m;
            m.set_cd( vec3(0.8f, 0.8f, 0.8f) );
            m.set_kd( 1.0f );
            m.set_ks( 1.0f );
            m.set_specular_exp( 32.0f );
            impl_->materials.push_back(m);
        }

        impl_->host_bvh = build<host_bvh_type>(impl_->triangles.data(), impl_->triangles.size());

        opencover::cover->getObjectsRoot()->setNodeMask
        (
            opencover::cover->getObjectsRoot()->getNodeMask()
         & ~opencover::VRViewer::instance()->getCullMask()
        );
    }

    // Sched params

    auto osg_cam = opencover::coVRConfig::instance()->channels[0].camera;

    auto t = opencover::cover->getXformMat();
    auto s = opencover::cover->getObjectsScale()->getMatrix();
    // TODO: understand COVER API..
//  auto v = opencover::cover->getViewerMat();
    auto v = opencover::coVRConfig::instance()->channels[0].rightView;
    auto osg_view_matrix = s * t * v;
    auto osg_proj_matrix = opencover::coVRConfig::instance()->channels[0].rightProj;
    auto osg_viewport = osg_cam->getViewport();

    float view[16];
    float proj[16];

    std::copy(osg_view_matrix.ptr(), osg_view_matrix.ptr() + 16, view);
    std::copy(osg_proj_matrix.ptr(), osg_proj_matrix.ptr() + 16, proj);

    mat4 view_matrix(view);
    mat4 proj_matrix(proj);
    recti viewport(osg_viewport->x(), osg_viewport->y(), osg_viewport->width(), osg_viewport->height());

    auto sparams = make_sched_params<pixel_sampler::uniform_type>( view_matrix, proj_matrix, viewport, impl_->host_rt );

    if (impl_->viewport != viewport)
    {
        impl_->host_rt.resize(viewport[2], viewport[3]);
        impl_->viewport = viewport;
    }

    // Kernel params

    aligned_vector<host_bvh_type::bvh_ref> host_primitives;
    host_primitives.push_back(impl_->host_bvh.ref());

    vec4 lpos;
    glGetLightfv(GL_LIGHT0, GL_POSITION, lpos.data());

    aligned_vector<point_light<float>> lights;
    vec3 light0_pos = (inverse(view_matrix) * lpos).xyz();
    lights.push_back({ light0_pos });

    auto kparams = make_params
    (
        host_primitives.data(),
        host_primitives.data() + host_primitives.size(),
        impl_->normals.data(),
        impl_->materials.data(),
        lights.data(),
        lights.data() + lights.size()
    );

    // Render

    auto kern =  simple::kernel<decltype(kparams)>();
    kern.params = kparams;
    impl_->host_sched.frame(kern, sparams);

    // TODO: generate depth buffer and use RGB render target
    glDepthMask(GL_FALSE);
    glPixelTransferf(GL_ALPHA_SCALE, 0.0f);

    impl_->host_rt.display_color_buffer();
}

}} // namespace visionaray::cover

COVERPLUGIN(visionaray::cover::Visionaray)
<commit_msg>Fix debug build<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <cassert>

#include <algorithm>
#include <iostream>
#include <limits>
#include <ostream>

#include <GL/glew.h>

#include <osg/io_utils>
#include <osg/Material>
#include <osg/MatrixTransform>
#include <osg/StateSet>
#include <osg/TriangleFunctor>

#include <cover/coVRConfig.h>
#include <cover/coVRPluginSupport.h>
#include <cover/VRViewer.h>

#include <visionaray/detail/aligned_vector.h>
#include <visionaray/math/math.h>
#include <visionaray/bvh.h>
#include <visionaray/kernels.h>
#include <visionaray/point_light.h>
#include <visionaray/render_target.h>
#include <visionaray/scheduler.h>

#include "visionaray_plugin.h"

namespace visionaray { namespace cover {

//-------------------------------------------------------------------------------------------------
// Type definitions
//

using triangle_type     = basic_triangle<3, float>;
using triangle_list     = aligned_vector<triangle_type>;
using normal_list       = aligned_vector<vec3>;
using material_list     = aligned_vector<phong<float>>;

using host_ray_type     = basic_ray<simd::float4>;
using host_bvh_type     = bvh<triangle_type>;
using host_sched_type   = tiled_sched<host_ray_type>;

//-------------------------------------------------------------------------------------------------
// Functor that stores triangles from osg::Drawable
//

class store_triangle
{
public:

    store_triangle() : triangles_(nullptr) {}

    void init(triangle_list& tris, normal_list& norms, unsigned geom_id)
    {
        triangles_  = &tris;
        normals_    = &norms;
        geom_id_    = geom_id;
    }

    void operator()(osg::Vec3 const& v1, osg::Vec3 const& v2, osg::Vec3 const& v3, bool) const
    {
        assert( triangles_ && normals_ );

        triangle_type tri;
        tri.prim_id = static_cast<unsigned>(triangles_->size());
        tri.geom_id = geom_id_;
        tri.v1 = vec3(v1.x(), v1.y(), v1.z());
        tri.e1 = vec3(v2.x(), v2.y(), v2.z()) - tri.v1;
        tri.e2 = vec3(v3.x(), v3.y(), v3.z()) - tri.v1;
        triangles_->push_back(tri);

        normals_->push_back( normalize(cross(tri.e1, tri.e2)) );

        assert( triangles_->size() == normals_->size() );
    }

private:

    // Store pointers because osg::TriangleFunctor is shitty..
    triangle_list*  triangles_;
    normal_list*    normals_;
    unsigned        geom_id_;

};

//-------------------------------------------------------------------------------------------------
// Visitor to acquire scene data
//

class get_scene_visitor : public osg::NodeVisitor
{
public:

    using base_type = osg::NodeVisitor;
    using base_type::apply;

    get_scene_visitor(triangle_list& tris, normal_list& norms, material_list& mats, TraversalMode tm)
        : base_type(tm)
        , triangles_(tris)
        , normals_(norms)
        , materials_(mats)
    {
    }

    void apply(osg::Geode& geode)
    {
        for (size_t i = 0; i < geode.getNumDrawables(); ++i)
        {
            auto drawable = geode.getDrawable(i);
            if (drawable)
            {
                auto set = drawable->getOrCreateStateSet();
                auto attr = set->getAttribute(osg::StateAttribute::MATERIAL);
                auto mat = dynamic_cast<osg::Material*>(attr);

                if (mat)
                {
                    auto cd = mat->getDiffuse(osg::Material::Face::FRONT);
                    auto cs = mat->getSpecular(osg::Material::Face::FRONT);

                    phong<float> vsnray_mat;
                    vsnray_mat.set_cd( vec3(cd.x(), cd.y(), cd.z()) );
                    vsnray_mat.set_kd( 1.0f );
                    vsnray_mat.set_ks( cs.x() ); // TODO: e.g. luminance?
                    vsnray_mat.set_specular_exp( mat->getShininess(osg::Material::Face::FRONT) );
                    materials_.push_back(vsnray_mat);
                }

                assert( static_cast<material_list::size_type>(static_cast<unsigned>(materials_.size()) == materials_.size()) );

                osg::TriangleFunctor<store_triangle> tf;
                tf.init( triangles_, normals_, materials_.size() == 0 ? 0 : static_cast<unsigned>(materials_.size() - 1) );
                drawable->accept(tf);
            }
        }

        base_type::traverse(geode);
    }

private:

    triangle_list&  triangles_;
    normal_list&    normals_;
    material_list&  materials_;

};

//-------------------------------------------------------------------------------------------------
// Private implementation
//

struct Visionaray::impl
{
    impl()
    {
    }

    triangle_list                       triangles;
    normal_list                         normals;
    material_list                       materials;
    host_bvh_type                       host_bvh;
    host_sched_type                     host_sched;
    cpu_buffer_rt                       host_rt;

    recti                               viewport;

    osg::ref_ptr<osg::Geode>            geode;
};

Visionaray::Visionaray()
    : impl_(new impl)
{
    setSupportsDisplayList(false);
}

Visionaray::Visionaray(Visionaray const& rhs, osg::CopyOp const& op)
    : Drawable(rhs, op)
    , impl_(new impl)
{
    setSupportsDisplayList(false);
}

Visionaray::~Visionaray()
{
    opencover::cover->getObjectsRoot()->removeChild(impl_->geode);
}

bool Visionaray::init()
{
    using namespace osg;

    opencover::VRViewer::instance()->culling(false);

    std::cout << "Init Visionaray Plugin!!" << std::endl;

    ref_ptr<osg::StateSet> state = new osg::StateSet();
    state->setGlobalDefaults();

    impl_->geode = new osg::Geode;
    impl_->geode->setName("Visionaray");
    impl_->geode->setStateSet(state);
    impl_->geode->addDrawable(this);

    opencover::cover->getScene()->addChild(impl_->geode);

    return true;
}

void Visionaray::preFrame()
{
}

void Visionaray::expandBoundingSphere(osg::BoundingSphere &bs)
{
    aabb bounds( vec3(std::numeric_limits<float>::max()), -vec3(std::numeric_limits<float>::max()) );
    for (auto const& tri : impl_->triangles)
    {
        auto v1 = tri.v1;
        auto v2 = tri.v1 + tri.e1;
        auto v3 = tri.v1 + tri.e2;

        bounds = combine(bounds, aabb(v1, v1));
        bounds = combine(bounds, aabb(v2, v2));
        bounds = combine(bounds, aabb(v3, v3));
    }

    auto c = bounds.center();
    osg::BoundingSphere::vec_type center(c.x, c.y, c.z);
    osg::BoundingSphere::value_type radius = length( c - bounds.min );
    bs.set(center, radius);
}

void Visionaray::drawImplementation(osg::RenderInfo&) const
{
    // TODO?

    static bool glewed = false;

    if (!glewed)
    {
        glewed = glewInit() == GLEW_OK;
    }

    // Scene data

    if (impl_->triangles.size() == 0)
    {
        // TODO: no dynamic scenes for now :(
        get_scene_visitor visitor(impl_->triangles, impl_->normals, impl_->materials,
            osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
        visitor.apply(*opencover::cover->getObjectsRoot());

        if (impl_->triangles.size() == 0)
        {
            return;
        }

        if (impl_->materials.size() == 0)
        {
            phong<float> m;
            m.set_cd( vec3(0.8f, 0.8f, 0.8f) );
            m.set_kd( 1.0f );
            m.set_ks( 1.0f );
            m.set_specular_exp( 32.0f );
            impl_->materials.push_back(m);
        }

        impl_->host_bvh = build<host_bvh_type>(impl_->triangles.data(), impl_->triangles.size());

        opencover::cover->getObjectsRoot()->setNodeMask
        (
            opencover::cover->getObjectsRoot()->getNodeMask()
         & ~opencover::VRViewer::instance()->getCullMask()
        );
    }

    // Sched params

    auto osg_cam = opencover::coVRConfig::instance()->channels[0].camera;

    auto t = opencover::cover->getXformMat();
    auto s = opencover::cover->getObjectsScale()->getMatrix();
    // TODO: understand COVER API..
//  auto v = opencover::cover->getViewerMat();
    auto v = opencover::coVRConfig::instance()->channels[0].rightView;
    auto osg_view_matrix = s * t * v;
    auto osg_proj_matrix = opencover::coVRConfig::instance()->channels[0].rightProj;
    auto osg_viewport = osg_cam->getViewport();

    float view[16];
    float proj[16];

    std::copy(osg_view_matrix.ptr(), osg_view_matrix.ptr() + 16, view);
    std::copy(osg_proj_matrix.ptr(), osg_proj_matrix.ptr() + 16, proj);

    mat4 view_matrix(view);
    mat4 proj_matrix(proj);
    recti viewport(osg_viewport->x(), osg_viewport->y(), osg_viewport->width(), osg_viewport->height());

    auto sparams = make_sched_params<pixel_sampler::uniform_type>( view_matrix, proj_matrix, viewport, impl_->host_rt );

    if (impl_->viewport != viewport)
    {
        impl_->host_rt.resize(viewport[2], viewport[3]);
        impl_->viewport = viewport;
    }

    // Kernel params

    aligned_vector<host_bvh_type::bvh_ref> host_primitives;
    host_primitives.push_back(impl_->host_bvh.ref());

    vec4 lpos;
    glGetLightfv(GL_LIGHT0, GL_POSITION, lpos.data());

    aligned_vector<point_light<float>> lights;
    vec3 light0_pos = (inverse(view_matrix) * lpos).xyz();
    lights.push_back({ light0_pos });

    auto kparams = make_params
    (
        host_primitives.data(),
        host_primitives.data() + host_primitives.size(),
        impl_->normals.data(),
        impl_->materials.data(),
        lights.data(),
        lights.data() + lights.size()
    );

    // Render

    auto kern =  simple::kernel<decltype(kparams)>();
    kern.params = kparams;
    impl_->host_sched.frame(kern, sparams);

    // TODO: generate depth buffer and use RGB render target
    glDepthMask(GL_FALSE);
    glPixelTransferf(GL_ALPHA_SCALE, 0.0f);

    impl_->host_rt.display_color_buffer();
}

}} // namespace visionaray::cover

COVERPLUGIN(visionaray::cover::Visionaray)
<|endoftext|>


<commit_before>#ifdef TREE_HPP

#include <cstddef>
#include <iostream>

template < class T >
Tree< T >::Tree() {
    this->root = nullptr;
}

template < class T >
void Tree< T >::push( const T value ) {
    if( this->root == nullptr ) {
        this->root = new Node< T >( value, nullptr, nullptr );
    } else {
        push( &( this->root ), value );
    }
}

template < class T >
void Tree< T >::push( Node< T >** node, T value ) {
    if( node == nullptr ) {
        *node = new Node< T >( value, nullptr, nullptr );
        return;

    } else if( value < ( *node )->getValue() ) {
        push( &( ( *node )->left ), value );
    } else if( value > ( *node )->getValue() ) {
        push( &( ( *node )->right ), value );
    } else {
        throw std::runtime_error( "Duplicate value" );
    }
}

#endif<commit_msg>Correção do método push<commit_after>#ifdef TREE_HPP

#include <cstddef>
#include <iostream>

template < class T >
Tree< T >::Tree() {
    this->root = nullptr;
}

template < class T >
void Tree< T >::push( const T value ) {
    push( &( this->root ), value );
}

template < class T >
void Tree< T >::push( Node< T >** node, T value ) {
    if( *node == nullptr ) {
        *node = new Node< T >( value, nullptr, nullptr );
        return;

    } else if( value < ( *node )->getValue() ) {
        push( &( ( *node )->left ), value );
    } else if( value > ( *node )->getValue() ) {
        push( &( ( *node )->right ), value );
    } else {
        throw std::runtime_error( "Duplicate value" );
    }
}

#endif<|endoftext|>


<commit_before>/*
 * Copyright 2004-2015 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is 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 "processTokens.h"

#include "chapel.tab.h"
#include "countTokens.h"
#include "misc.h"
#include "stringutil.h"
#include "yy.h"

#include <cstring>
#include <cctype>

static int stringBuffLen = 0;
static int stringLen = 0;
static char* stringBuffer = NULL;

static void newString(void) {
  stringLen = 0;
  if (stringBuffLen) {
    stringBuffer[stringLen] = '\0';
  }
}

// Returns the hexadecimal character for 0-16.
static char toHex(char c)
{
  if (0 <= c && c <= 9) return '0' + c;
  else return 'A' + (c - 10);
}

static void addCharMaybeEscape(char c, bool canEscape) {
  int escape = canEscape && !(isascii(c) && isprint(c));
  int charlen = escape ? 4 : 1; // convert nonasci to \xNN

  if (stringLen+charlen+1 > stringBuffLen) {
    stringBuffLen = 2*(stringBuffLen + charlen);
    stringBuffer = (char*)realloc(stringBuffer, stringBuffLen*sizeof(char));
  }

  if (escape) {
    stringBuffer[stringLen++] = '\\';
    stringBuffer[stringLen++] = 'x';
    stringBuffer[stringLen++] = toHex(((unsigned char)c) >> 4);
    stringBuffer[stringLen++] = toHex(c & 0xf);
  } else {
    stringBuffer[stringLen++] = c;
  }
  stringBuffer[stringLen] = '\0';
}

static inline void addCharString(char c) {
  addCharMaybeEscape(c, true);
}

static inline void addChar(char c) {
  addCharMaybeEscape(c, false);
}

static void addString(const char* str) {
  int i;
  for( i = 0; str[i]; i++ ) addChar(str[i]);
}

void processNewline(void) {
  chplLineno++;
  yylloc.first_column = yylloc.last_column = 0;
  yylloc.first_line = yylloc.last_line = chplLineno;
  countNewline();
}

char* eatStringLiteral(const char* startChar) {
  register int c;
  const char startCh = *startChar;

  newString();
    while ((c = getNextYYChar()) != startCh && c != 0) {
      if (c == '\n')
     {
        yytext[0] = '\0'; yyerror(
          "end-of-line in a string literal without a preceeding backslash");
     } else {
      if (startCh == '\'' && c == '\"') {
        addCharString('\\');
      }
      addCharString(c);
     }
      if (c == '\\') {
        c = getNextYYChar();
        if (c == '\n')
        {
          processNewline(); addCharString('n');
        } else if (c != 0) {
          addCharString(c);
        }
        else
          break;
      }
    } /* eat up string */
    if (c == 0) {
      yyerror("EOF in string");
    }
  return stringBuffer;
}

void processSingleLineComment(void) {
  register int c;

  newString();
  countCommentLine();
  while (1) {
    while ( (c = getNextYYChar()) != '\n' && c != 0) {
      addChar(c);
    }    /* eat up text of comment */
    countSingleLineComment(stringBuffer);
    if (c != 0) {
      processNewline();
    }
    break;
  }
}

void processMultiLineComment() {
  int c;
  int lastc;
  int lastlastc;
  int depth;

  c = 0;
  lastc = 0;
  depth = 1;

  newString();
  countCommentLine();

  int labelIndex = 0;
  int len = strlen(fDocsCommentLabel);
  if (len >= 2) {
    labelIndex = 2;
  }

  std::string wholeComment = "";

  while (depth > 0) {
    lastlastc = lastc;
    lastc = c;
    c = getNextYYChar();
    if( c == '\n' ) {
      countMultiLineComment(stringBuffer);
      processNewline();
      if (fDocs && labelIndex == len) {
        wholeComment += stringBuffer;
        wholeComment += '\n';
      }
      newString();
      countCommentLine();
    } else {
      if ((labelIndex < len) && (labelIndex != -1)) {
        if (c == fDocsCommentLabel[labelIndex]) {
          labelIndex++;
        } else {
          labelIndex = -1;
        }
      }
      addChar(c);
    }
    if( lastc == '*' && c == '/' && lastlastc != '/' ) { // close comment
      depth--;
    } else if( lastc == '/' && c == '*' ) { // start nested
      depth++;
    } else if( c == 0 ) {
      yyerror( "EOF in comment" );
    }
  }

  // back up two to not print */ again.
  if( stringLen >= 2 ) stringLen -= 2;
  // back up further if the user has specified a special form of commenting
  if (len > 2 && labelIndex == len) stringLen -= (len - 2);
  stringBuffer[stringLen] = '\0';

  // Saves the comment grabbed to the comment field of the location struct,
  // for use when the --docs flag is implemented
  if (fDocs && labelIndex == len) {
    wholeComment += stringBuffer;
    if (len > 2) {
      len -= 2;
      wholeComment = wholeComment.substr(len);
      // Trim the start of the string if the user has specified a special form
      // of commenting
    }

    // Also, only need to fix indentation failure when the comment matters
    size_t location = wholeComment.find("\\x09");
    while (location != std::string::npos) {
      wholeComment = wholeComment.substr(0, location) + wholeComment.substr(location + 4);
      wholeComment.insert(location, "\t");
      location = wholeComment.find("\\x09");
    }
    yylloc.comment = (char *)astr(wholeComment.c_str());
  }

  countMultiLineComment(stringBuffer);
  newString();
}

char* eatExternCode() {
  // Note - when the lexer calls this function, it has already
  // consumed the first {
  int depth = 1;
  int c = 0, lastc = 0;
  const int in_code = 0;
  const int in_single_quote = 1;
  const int in_single_quote_backslash = 2;
  const int in_double_quote = 3;
  const int in_double_quote_backslash = 4;
  const int in_single_line_comment = 5;
  const int in_single_line_comment_backslash = 6;
  const int in_multi_line_comment = 7;
  int state = 0;

  newString();

  // First, store the line information.
  addString("#line ");
  addString(istr(chplLineno));
  addString(" \"");
  addString(yyfilename);
  addString("\" ");
  addString("\n");

  // Now, append the C code until we get to a }.
  while (depth > 0) {
    lastc = c;
    c = getNextYYChar();

    if (c == 0) {
      switch (state) {
        case in_code:
          // there was no match to the {
          yyerror("Missing } in extern block");
          break;
        case in_single_quote:
        case in_single_quote_backslash:
          yyerror("Runaway \'string\' in extern block");
          break;
        case in_double_quote:
        case in_double_quote_backslash:
          yyerror("Runaway \"string\" in extern block");
          break;
        case in_single_line_comment:
          yyerror("Missing newline after extern block // comment");
          break;
        case in_multi_line_comment:
          yyerror("Runaway /* comment */ in extern block");
          break;
      }
      break;
    }

    addChar(c);

    if( c == '\n' ) processNewline();

    // Now update state (are we in a comment? a string?)
    switch (state) {
      case in_code:
        if( c == '\'' ) state = in_single_quote;
        else if( c == '"' ) state = in_double_quote;
        else if( lastc == '/' && c == '/' ) state = in_single_line_comment;
        else if( lastc == '/' && c == '*' ) state = in_multi_line_comment;
        else if( c == '{' ) depth++;
        else if( c == '}' ) depth--;
        break;
      case in_single_quote:
        if( c == '\\' ) state = in_single_quote_backslash;
        else if( c == '\'' ) state = in_code;
        break;
      case in_single_quote_backslash:
        state = in_single_quote;
        break;
      case in_double_quote:
        if( c == '\\' ) state = in_double_quote_backslash;
        else if( c == '"' ) state = in_code;
        break;
      case in_double_quote_backslash:
        state = in_double_quote;
        break;
      case in_single_line_comment:
        if( c == '\n' ) state = in_code;
        break;
      case in_single_line_comment_backslash:
        if( c == ' ' || c == '\t' || c == '\n' )
          state = in_single_line_comment_backslash;
        else state = in_single_line_comment;
        break;
      case in_multi_line_comment:
        if( lastc == '*' && c == '/' ) state = in_code;
        break;
    }
  }

  //save the C String
  //eliminate the final '{'
  if (stringLen >=1) stringLen -= 1;
  stringBuffer[stringLen] = '\0';

  return stringBuffer;
}

void processWhitespace(const char* tabOrSpace) {
  // might eventually want to keep track of column numbers and do
  // something here
}

void processInvalidToken() {
  yyerror("Invalid token");
}
<commit_msg>processTokens.cpp: yy.h must preceed chapel.tab.h for Bison 2.3<commit_after>/*
 * Copyright 2004-2015 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is 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 "processTokens.h"

#include "countTokens.h"
#include "misc.h"
#include "stringutil.h"

#include "yy.h"
#include "chapel.tab.h"

#include <cstring>
#include <cctype>

static int stringBuffLen = 0;
static int stringLen = 0;
static char* stringBuffer = NULL;

static void newString(void) {
  stringLen = 0;
  if (stringBuffLen) {
    stringBuffer[stringLen] = '\0';
  }
}

// Returns the hexadecimal character for 0-16.
static char toHex(char c)
{
  if (0 <= c && c <= 9) return '0' + c;
  else return 'A' + (c - 10);
}

static void addCharMaybeEscape(char c, bool canEscape) {
  int escape = canEscape && !(isascii(c) && isprint(c));
  int charlen = escape ? 4 : 1; // convert nonasci to \xNN

  if (stringLen+charlen+1 > stringBuffLen) {
    stringBuffLen = 2*(stringBuffLen + charlen);
    stringBuffer = (char*)realloc(stringBuffer, stringBuffLen*sizeof(char));
  }

  if (escape) {
    stringBuffer[stringLen++] = '\\';
    stringBuffer[stringLen++] = 'x';
    stringBuffer[stringLen++] = toHex(((unsigned char)c) >> 4);
    stringBuffer[stringLen++] = toHex(c & 0xf);
  } else {
    stringBuffer[stringLen++] = c;
  }
  stringBuffer[stringLen] = '\0';
}

static inline void addCharString(char c) {
  addCharMaybeEscape(c, true);
}

static inline void addChar(char c) {
  addCharMaybeEscape(c, false);
}

static void addString(const char* str) {
  int i;
  for( i = 0; str[i]; i++ ) addChar(str[i]);
}

void processNewline(void) {
  chplLineno++;
  yylloc.first_column = yylloc.last_column = 0;
  yylloc.first_line = yylloc.last_line = chplLineno;
  countNewline();
}

char* eatStringLiteral(const char* startChar) {
  register int c;
  const char startCh = *startChar;

  newString();
    while ((c = getNextYYChar()) != startCh && c != 0) {
      if (c == '\n')
     {
        yytext[0] = '\0'; yyerror(
          "end-of-line in a string literal without a preceeding backslash");
     } else {
      if (startCh == '\'' && c == '\"') {
        addCharString('\\');
      }
      addCharString(c);
     }
      if (c == '\\') {
        c = getNextYYChar();
        if (c == '\n')
        {
          processNewline(); addCharString('n');
        } else if (c != 0) {
          addCharString(c);
        }
        else
          break;
      }
    } /* eat up string */
    if (c == 0) {
      yyerror("EOF in string");
    }
  return stringBuffer;
}

void processSingleLineComment(void) {
  register int c;

  newString();
  countCommentLine();
  while (1) {
    while ( (c = getNextYYChar()) != '\n' && c != 0) {
      addChar(c);
    }    /* eat up text of comment */
    countSingleLineComment(stringBuffer);
    if (c != 0) {
      processNewline();
    }
    break;
  }
}

void processMultiLineComment() {
  int c;
  int lastc;
  int lastlastc;
  int depth;

  c = 0;
  lastc = 0;
  depth = 1;

  newString();
  countCommentLine();

  int labelIndex = 0;
  int len = strlen(fDocsCommentLabel);
  if (len >= 2) {
    labelIndex = 2;
  }

  std::string wholeComment = "";

  while (depth > 0) {
    lastlastc = lastc;
    lastc = c;
    c = getNextYYChar();
    if( c == '\n' ) {
      countMultiLineComment(stringBuffer);
      processNewline();
      if (fDocs && labelIndex == len) {
        wholeComment += stringBuffer;
        wholeComment += '\n';
      }
      newString();
      countCommentLine();
    } else {
      if ((labelIndex < len) && (labelIndex != -1)) {
        if (c == fDocsCommentLabel[labelIndex]) {
          labelIndex++;
        } else {
          labelIndex = -1;
        }
      }
      addChar(c);
    }
    if( lastc == '*' && c == '/' && lastlastc != '/' ) { // close comment
      depth--;
    } else if( lastc == '/' && c == '*' ) { // start nested
      depth++;
    } else if( c == 0 ) {
      yyerror( "EOF in comment" );
    }
  }

  // back up two to not print */ again.
  if( stringLen >= 2 ) stringLen -= 2;
  // back up further if the user has specified a special form of commenting
  if (len > 2 && labelIndex == len) stringLen -= (len - 2);
  stringBuffer[stringLen] = '\0';

  // Saves the comment grabbed to the comment field of the location struct,
  // for use when the --docs flag is implemented
  if (fDocs && labelIndex == len) {
    wholeComment += stringBuffer;
    if (len > 2) {
      len -= 2;
      wholeComment = wholeComment.substr(len);
      // Trim the start of the string if the user has specified a special form
      // of commenting
    }

    // Also, only need to fix indentation failure when the comment matters
    size_t location = wholeComment.find("\\x09");
    while (location != std::string::npos) {
      wholeComment = wholeComment.substr(0, location) + wholeComment.substr(location + 4);
      wholeComment.insert(location, "\t");
      location = wholeComment.find("\\x09");
    }
    yylloc.comment = (char *)astr(wholeComment.c_str());
  }

  countMultiLineComment(stringBuffer);
  newString();
}

char* eatExternCode() {
  // Note - when the lexer calls this function, it has already
  // consumed the first {
  int depth = 1;
  int c = 0, lastc = 0;
  const int in_code = 0;
  const int in_single_quote = 1;
  const int in_single_quote_backslash = 2;
  const int in_double_quote = 3;
  const int in_double_quote_backslash = 4;
  const int in_single_line_comment = 5;
  const int in_single_line_comment_backslash = 6;
  const int in_multi_line_comment = 7;
  int state = 0;

  newString();

  // First, store the line information.
  addString("#line ");
  addString(istr(chplLineno));
  addString(" \"");
  addString(yyfilename);
  addString("\" ");
  addString("\n");

  // Now, append the C code until we get to a }.
  while (depth > 0) {
    lastc = c;
    c = getNextYYChar();

    if (c == 0) {
      switch (state) {
        case in_code:
          // there was no match to the {
          yyerror("Missing } in extern block");
          break;
        case in_single_quote:
        case in_single_quote_backslash:
          yyerror("Runaway \'string\' in extern block");
          break;
        case in_double_quote:
        case in_double_quote_backslash:
          yyerror("Runaway \"string\" in extern block");
          break;
        case in_single_line_comment:
          yyerror("Missing newline after extern block // comment");
          break;
        case in_multi_line_comment:
          yyerror("Runaway /* comment */ in extern block");
          break;
      }
      break;
    }

    addChar(c);

    if( c == '\n' ) processNewline();

    // Now update state (are we in a comment? a string?)
    switch (state) {
      case in_code:
        if( c == '\'' ) state = in_single_quote;
        else if( c == '"' ) state = in_double_quote;
        else if( lastc == '/' && c == '/' ) state = in_single_line_comment;
        else if( lastc == '/' && c == '*' ) state = in_multi_line_comment;
        else if( c == '{' ) depth++;
        else if( c == '}' ) depth--;
        break;
      case in_single_quote:
        if( c == '\\' ) state = in_single_quote_backslash;
        else if( c == '\'' ) state = in_code;
        break;
      case in_single_quote_backslash:
        state = in_single_quote;
        break;
      case in_double_quote:
        if( c == '\\' ) state = in_double_quote_backslash;
        else if( c == '"' ) state = in_code;
        break;
      case in_double_quote_backslash:
        state = in_double_quote;
        break;
      case in_single_line_comment:
        if( c == '\n' ) state = in_code;
        break;
      case in_single_line_comment_backslash:
        if( c == ' ' || c == '\t' || c == '\n' )
          state = in_single_line_comment_backslash;
        else state = in_single_line_comment;
        break;
      case in_multi_line_comment:
        if( lastc == '*' && c == '/' ) state = in_code;
        break;
    }
  }

  //save the C String
  //eliminate the final '{'
  if (stringLen >=1) stringLen -= 1;
  stringBuffer[stringLen] = '\0';

  return stringBuffer;
}

void processWhitespace(const char* tabOrSpace) {
  // might eventually want to keep track of column numbers and do
  // something here
}

void processInvalidToken() {
  yyerror("Invalid token");
}
<|endoftext|>


<commit_before>/*
fontResource.cpp
This file is part of:
GAME PENCIL ENGINE
https://create.pawbyte.com
Copyright (c) 2014-2020 Nathan Hurde, Chase Lee.

Copyright (c) 2014-2020 PawByte LLC.
Copyright (c) 2014-2020 Game Pencil Engine contributors ( Contributors Page )

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

-Game Pencil Engine <https://create.pawbyte.com>

*/

#include "font_resource.h"
#include "gpe_editor_settings.h"

//

std::string SUPPORTED_FONT_EXT[FONT_FILE_TYPES];

fontResource::fontResource(GPE_GeneralResourceContainer * pFolder)
{
    projectParentFolder = pFolder;
    fontInEditor = NULL;
    resourceFileName = " ";
    for( int i = 0; i < FONT_FILE_TYPES; i++)
    {
        storedFontFileNames[i] = "";
    }
    resourceName = " ";
    fontId = -1;
    fontType = -1;
    fontWidth = 32;
    fontHeight = 32;
    fontSize = 12;
    fontSizeField = new GPE_TextInputNumber("Range: 8 to 512",true,2,256);
    fontPreviewTextField = new GPE_TextInputBasic("ABCD012456789","Previewed Text");
    fontPreviewTextField->set_label("Preview Text");
    fontSizeField->set_string("12");
    fontSizeField->set_label("Font Size");
    if( saveResourceButton!=NULL)
    {
        fontSizeField->set_coords(-1,saveResourceButton->get_ypos()+saveResourceButton->get_height()+GENERAL_GPE_GUI_PADDING+48);
    }
    fontTypeButtonController = new GPE_RadioButtonControllerBasic("Font Type", true,1);
    fontTypeButtonController->add_opton("Normal Font");
    fontTypeButtonController->add_opton("MonoSpace Font");
    loadResourceButton->set_name("Load Custom Font");
    saveResourceButton->set_width( loadResourceButton->get_width() );
    fontFamilyName = "";

    openExternalEditorButton = new GPE_ToolIconButton( APP_DIRECTORY_NAME+"resources/gfx/iconpacks/fontawesome/rocket.png","Use External Editor" );
}

fontResource::~fontResource()
{
    if( fontTypeButtonController!=NULL)
    {
        delete fontTypeButtonController;
        fontTypeButtonController = NULL;
    }
    if( fontPreviewTextField!=NULL)
    {
        delete fontPreviewTextField;
        fontPreviewTextField = NULL;
    }
    if( fontSizeField!=NULL)
    {
        delete fontSizeField;
        fontSizeField = NULL;
    }
    if( fontInEditor!=NULL)
    {
        gfs->close_font(fontInEditor);
        fontInEditor= NULL;
    }
    if( openExternalEditorButton!=NULL)
    {
        delete openExternalEditorButton;
        openExternalEditorButton= NULL;
    }
}

bool fontResource::build_intohtml5_file(std::ofstream * fileTarget, int leftTabAmount)
{
    if( fileTarget!=NULL && fileTarget->is_open() )
    {
        std::string nestedTabsStr = generate_tabs( leftTabAmount  );

        *fileTarget << nestedTabsStr << "var " << resourceName << " =  GPE.rsm.add_font(";
        *fileTarget << int_to_string (exportBuildGlobalId ) +",'";
        if( (int)fontFamilyName.size() > 4)
        {
            *fileTarget << fontFamilyName+"',";
        }
        else
        {
            *fileTarget << "Arial',";
        }
        for( int i = 0; i < FONT_FILE_TYPES; i++)
        {
            //*fileTarget  << "'resources/animations/"+get_short_filename (animInEditor->fileName,true )+"',";
            if( (int)storedFontFileNames[i].size() > 4)
            {
                *fileTarget << "'resources/fonts/"+get_short_filename( storedFontFileNames[i],true) <<  "',";
            }
            else
            {
                *fileTarget << "'',";
            }
        }
        if( fontInEditor==NULL )
        {
            fontSize = fontSizeField->get_held_number();
        }
        if( fontSize <=8)
        {
            fontSize = 8;
        }
        if( fontSize >=256)
        {
            fontSize = 256;
        }
        *fileTarget << int_to_string (fontSize ) +",";

        *fileTarget << int_to_string (fontWidth ) +",";
        *fileTarget << int_to_string (fontHeight ) +",";
        if( fontTypeButtonController!=NULL)
        {
            *fileTarget << int_to_string (fontTypeButtonController->get_selected_id() );
        }
        else
        {
            *fileTarget << "0";
        }

        *fileTarget << ");\n";
        return true;
    }
    return false;

}

bool fontResource::build_css3_file(std::ofstream * fileTarget, int leftTabAmount)
{
    if( fileTarget!=NULL && fileTarget->is_open() )
    {
        std::string nestedTabsStr = generate_tabs( leftTabAmount  );

        bool foundHeldFont = false;
        for( int i = 0; i < FONT_FILE_TYPES; i++)
        {
            if( (int)storedFontFileNames[i].size() > 0)
            {
                foundHeldFont = true;
                break;
            }
        }
        if( foundHeldFont)
        {
            *fileTarget << nestedTabsStr << "@font-face{\n";
            *fileTarget << nestedTabsStr << "font-family: '"+fontFamilyName+"';\n";
            if( (int)storedFontFileNames[FONT_EOT].size() > 0)
            {
                *fileTarget << nestedTabsStr << "src: url('../resources/fonts/" << get_short_filename(storedFontFileNames[FONT_EOT],true)   << "'),\n";
                *fileTarget << nestedTabsStr << "src: url('../resources/fonts/" << get_short_filename(storedFontFileNames[FONT_EOT],true ) << "?#iefix') format('embedded-opentype'),\n,";
            }
            *fileTarget << nestedTabsStr << "src: local('☺')";
            if( (int)storedFontFileNames[FONT_WOFF].size() > 0)
            {
                *fileTarget << nestedTabsStr << ",\n" << "url('../resources/fonts/" << get_short_filename(storedFontFileNames[FONT_WOFF],true)   << "') format('woff')";
            }
            if( (int)storedFontFileNames[FONT_TTF].size() > 0)
            {
                *fileTarget << nestedTabsStr << ",\n" << "url('../resources/fonts/" << get_short_filename(storedFontFileNames[FONT_TTF],true)   << "') format('truetype')";
            }
            if( (int)storedFontFileNames[FONT_SVG].size() > 0)
            {
                *fileTarget << nestedTabsStr << "\n" << "url('../resources/fonts/" << get_short_filename(storedFontFileNames[FONT_SVG],true)   << "#" << fontFamilyName << "') format('svg')";
            }
            *fileTarget << nestedTabsStr << ";\n" << "font-weight: normal;\n";
            *fileTarget << nestedTabsStr << "font-style: normal;\n";
            *fileTarget << nestedTabsStr << "}\n";
        }
    }
    return false;
}

bool fontResource::build_intocpp_file(std::ofstream * fileTarget, int leftTabAmount  )
{
    return true;
}

void fontResource::compile_cpp()
{

}

bool fontResource::include_local_files( std::string pBuildDir , int buildType )
{
    appendToFile(get_user_settings_folder()+"resources_check.txt",get_name() +"...");

    bool fontNotCopied = false;
    std::string copyFileDestination;
    for( int jFontType = 0; jFontType < FONT_FILE_TYPES; jFontType++)
    {
        if( (int)storedFontFileNames[jFontType].size() > 3 )
        {
            copyFileDestination = pBuildDir+"/resources/fonts/"+get_short_filename(storedFontFileNames[jFontType],true);
            if( copy_file( storedFontFileNames[jFontType],copyFileDestination)==false )
            {
                appendToFile(get_user_settings_folder()+"resources_check.txt","Unable to copy ["+storedFontFileNames[jFontType]+"] to ["+copyFileDestination+"]...");
                return fontNotCopied;
            }
        }
    }

    return !fontNotCopied;
}

void fontResource::load_font(std::string newFileName, int newFontSize )
{
    if( (int)newFileName.size() > 0)
    {
        if( newFontSize < 0 && fontSizeField->get_held_number() > 0 )
        {
            newFontSize = fontSizeField->get_held_number();
        }
        else if( newFontSize < 0 )
        {
            newFontSize = 8;
        }
        else if(newFontSize > 512)
        {
            newFontSize = 512;
        }
        fontSizeField->set_string( int_to_string(newFontSize) );
        fontSize = newFontSize;

        //Saves the font where possible...
        if( get_file_ext(newFileName)=="eot" || get_file_ext(newFileName)=="EOT" )
        {
            std::string copyDestinationStr = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/"+ get_short_filename(newFileName,true);
            storedFontFileNames[FONT_EOT] = copyDestinationStr;
            copy_file(newFileName.c_str(),copyDestinationStr );
        }
        else if( get_file_ext(newFileName)=="svg" || get_file_ext(newFileName)=="SVG" )
        {
            std::string copyDestinationStr = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/"+ get_short_filename(newFileName,true);
            storedFontFileNames[FONT_SVG] = copyDestinationStr;
            copy_file(newFileName.c_str(),copyDestinationStr );
        }
        else if( get_file_ext(newFileName)=="otf" || get_file_ext(newFileName)=="OTF" )
        {
            if( fontInEditor!=NULL)
            {
                gfs->close_font(fontInEditor);
                fontInEditor = NULL;
            }
            fontInEditorFileName = get_short_filename(newFileName,true);
            std::string copyDestinationStr = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/"+ fontInEditorFileName;
            copy_file(newFileName.c_str(),copyDestinationStr );

            fontInEditor = gfs->open_font(copyDestinationStr.c_str(),newFontSize,false,"Custom Font");
            fontFamilyName =fontInEditor->get_family_name();
            if( fontInEditor==NULL)
            {
                display_user_alert("Font Resource Editor","Oh dear! Houston has a problem reading this .ttf font"+newFileName+"/"+int_to_string(newFontSize)+"...");
            }
            else
            {
                fontInEditorFileName = get_short_filename(newFileName,true);
                fontInEditor->get_metrics( "AgyW", &fontWidth, &fontHeight);
                fontWidth/=4;
                std::string copyDestinationStr = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/"+ get_short_filename(newFileName,true);
                storedFontFileNames[FONT_OTF] = copyDestinationStr;
                fontInEditor->get_metrics( "AgyW", &fontWidth, &fontHeight);
                fontWidth/=4;

            }
        }
        else if( get_file_ext(newFileName)=="ttf" || get_file_ext(newFileName)=="TTF" )
        {
            if( fontInEditor!=NULL)
            {
                gfs->close_font(fontInEditor);
                fontInEditor = NULL;
            }
            fontInEditorFileName = get_short_filename(newFileName,true);
            std::string copyDestinationStr = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/"+ fontInEditorFileName;
            copy_file(newFileName.c_str(),copyDestinationStr );

            fontInEditor = gfs->open_font(copyDestinationStr.c_str(),newFontSize,false,"Custom Font");
            fontFamilyName =fontInEditor->get_family_name();
            if( fontInEditor==NULL)
            {
                display_user_alert("Font Resource Editor","Oh dear! Houston has a problem reading this .ttf font"+newFileName+"/"+int_to_string(newFontSize)+"...");
            }
            else
            {
                fontInEditorFileName = get_short_filename(newFileName,true);
                fontInEditor->get_metrics( "AgyW", &fontWidth, &fontHeight);
                fontWidth/=4;
                std::string copyDestinationStr = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/"+ get_short_filename(newFileName,true);
                storedFontFileNames[FONT_TTF] = copyDestinationStr;
                fontInEditor->get_metrics( "AgyW", &fontWidth, &fontHeight);
                fontWidth/=4;

            }
        }
        else if( get_file_ext(newFileName)=="woff" || get_file_ext(newFileName)=="WOFF" )
        {
            std::string copyDestinationStr = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/"+ get_short_filename(newFileName,true);
            storedFontFileNames[FONT_WOFF] = copyDestinationStr;
            copy_file(newFileName.c_str(),copyDestinationStr );
        }
        else if( get_file_ext(newFileName)=="woff2" || get_file_ext(newFileName)=="WOFF2" )
        {
            std::string copyDestinationStr = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/"+ get_short_filename(newFileName,true);
            storedFontFileNames[FONT_WOFF2] = copyDestinationStr;
            copy_file(newFileName.c_str(),copyDestinationStr );
        }
        else
        {
            display_user_alert("Font Resource Editor","Invalid Font File Type given. Please use .ttf files");
        }
    }
}

void fontResource::preprocess_self(std::string alternatePath)
{
    if( resourcePostProcessed ==false || file_exists(alternatePath) )
    {
        if( GPE_LOADER != NULL )
        {
            GPE_LOADER->update_submessages( "Processing Font", resourceName );
        }

        std::string otherColContainerName = "";

        std::string newFileIn ="";
        std::string soughtDir = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/";
        if( file_exists(alternatePath) )
        {
            newFileIn = alternatePath;
            soughtDir = get_path_from_file(newFileIn);
        }
        else
        {
            newFileIn = soughtDir + resourceName+".gpf";
        }
        std::ifstream gameResourceFileIn( newFileIn.c_str() );

        GPE_Report("Loading font - "+newFileIn);
        //If the level file could be loaded
        if( !gameResourceFileIn.fail() )
        {
            //makes sure the file is open
            if (gameResourceFileIn.is_open())
            {
                int equalPos = 0;
                std::string firstChar="";
                std::string section="";
                std::string keyString="";
                std::string valString="";
                std::string subValString="";
                std::string currLine="";
                std::string currLineToBeProcessed;
                float foundFileVersion = 0;
                std::string fFontFile = "";
                int tFontSize = 12;
                while ( gameResourceFileIn.good() )
                {
                    getline (gameResourceFileIn,currLine); //gets the next line of the file
                    currLineToBeProcessed  = trim_left_inplace(currLine);
                    currLineToBeProcessed  = trim_right_inplace(currLineToBeProcessed);

                    if( foundFileVersion <=0)
                    {
                        //Empty Line skipping is only allowed at the top of the file
                        if(!currLineToBeProcessed.empty() )
                        {
                            //Comment skipping is only allowed at the top of the file
                            if( currLineToBeProcessed[0]!= '#' && currLineToBeProcessed[0]!='/'  )
                            {
                                //searches for an equal character and parses through the variable
                                equalPos=currLineToBeProcessed.find_first_of("=");
                                if(equalPos!=(int)std::string::npos)
                                {
                                    //if the equalPos is present, then parse on through and carryon
                                    keyString = currLineToBeProcessed.substr(0,equalPos);
                                    valString = currLineToBeProcessed.substr(equalPos+1,currLineToBeProcessed.length());
                                    if( keyString=="Version")
                                    {
                                        foundFileVersion = string_to_float(valString);
                                    }
                                }
                            }
                        }
                    }
                    else if( foundFileVersion <= 2)
                    {
                        //Begin processing the file.
                        if(!currLineToBeProcessed.empty() )
                        {
                            equalPos=currLineToBeProcessed.find_first_of("=");
                            if(equalPos!=(int)std::string::npos)
                            {
                                //if the equalPos is present, then parse on through and carryon
                                keyString = currLineToBeProcessed.substr(0,equalPos);
                                valString = currLineToBeProcessed.substr(equalPos+1,currLineToBeProcessed.length());

                                if( keyString=="ResourceName")
                                {
                                    renameBox->set_string(valString);
                                }
                                else if( keyString=="FontSize")
                                {
                                    fontSizeField->set_string(valString);
                                    tFontSize = fontSizeField->get_held_number();
                                }
                                else if( keyString=="FontType")
                                {
                                    fontTypeButtonController->set_selection(string_to_int(valString,0));
                                }
                                if( keyString=="PreviewText")
                                {
                                    fontPreviewTextField->set_string(valString);
                                }
                                else
                                {
                                    for( int i = 0; i < FONT_FILE_TYPES; i++)
                                    {
                                        if( keyString==SUPPORTED_FONT_EXT[i]+"_File")
                                        {
                                            load_font( soughtDir+valString,tFontSize );
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        GPE_Report("Invalid FoundFileVersion ="+float_to_string(foundFileVersion)+".");
                    }
                }
            }
        }
    }
}

void fontResource::prerender_self( )
{
    standardEditableGameResource::prerender_self( );
    if( fontTypeButtonController!=NULL)
    {
        fontTypeButtonController->prerender_self( );
    }
}

void fontResource::process_self(GPE_Rect * viewedSpace,GPE_Rect * cam )
{
    viewedSpace = GPE_find_camera(viewedSpace);
    cam = GPE_find_camera(cam);
    if(cam!=NULL && viewedSpace!=NULL && PANEL_GENERAL_EDITOR!=NULL && fontSizeField!=NULL)
    {
        PANEL_GENERAL_EDITOR->clear_panel();
        PANEL_GENERAL_EDITOR->add_gui_element(renameBox,true);
        PANEL_GENERAL_EDITOR->add_gui_element(loadResourceButton,false);
        PANEL_GENERAL_EDITOR->add_gui_element(exportResourceButton,false);
        PANEL_GENERAL_EDITOR->add_gui_element(openExternalEditorButton,true);

        PANEL_GENERAL_EDITOR->add_gui_element(fontSizeField,true);
        PANEL_GENERAL_EDITOR->add_gui_element(fontPreviewTextField,true);
        PANEL_GENERAL_EDITOR->add_gui_element(fontTypeButtonController,true);
        PANEL_GENERAL_EDITOR->add_gui_element(confirmResourceButton,true);
        PANEL_GENERAL_EDITOR->add_gui_element(cancelResourceButton,true);
        int prevFontSize = fontSizeField->get_held_number();

        PANEL_GENERAL_EDITOR->process_self(NULL, NULL);
        if( openExternalEditorButton!=NULL &&  openExternalEditorButton->is_clicked() )
        {
            bool hasFileToOpen = false;
            int ii = 0;
            for( ii = 0; ii < FONT_FILE_TYPES; ii++)
            {
                if( (int)storedFontFileNames[ii].size() > 0)
                {
                    hasFileToOpen = true;
                    break;
                }
            }
            if( hasFileToOpen )
            {
                GPE_open_context_menu(-1,-1,400);
                for( ii = 0; ii < FONT_FILE_TYPES; ii++)
                {
                    if( (int)storedFontFileNames[ii].size() > 0)
                    {
                        MAIN_CONTEXT_MENU->add_menu_option("Edit "+storedFontFileNames[ii],ii,NULL,-1,NULL,true,true);
                    }
                }
                MAIN_CONTEXT_MENU->set_width( MAIN_CONTEXT_MENU->subOptionWidthSpace );
                int menuSelection = GPE_Get_Context_Result();
                if( menuSelection >=0 && menuSelection < FONT_FILE_TYPES)
                {
                    std::string fileToEdit = storedFontFileNames[menuSelection];

                    if( MAIN_EDITOR_SETTINGS!=NULL && MAIN_EDITOR_SETTINGS->pencilExternalEditorsFile[GPE_EXTERNAL_EDITOR_FONT]!=NULL)
                    {
                        GPE_OpenProgram(MAIN_EDITOR_SETTINGS->pencilExternalEditorsFile[GPE_EXTERNAL_EDITOR_FONT]->get_string(),fileToEdit, true );
                    }
                    else
                    {
                        GPE_OpenURL(fileToEdit);
                    }
                    /*
                    fileToEdit = "\"C:/Program Files (x86)/Audacity/audacity.exe\" \""+fileToEdit+"\"";
                    GPE_OpenURL(fileToEdit);*/
                    appendToFile(get_user_settings_folder()+"gpe_error_log2.txt","Attempting to edit ["+fileToEdit+"]...");
                }
            }
        }

        if( fontSizeField->is_valid() )
        {
            if( fontSizeField->get_held_number()!=prevFontSize && fontSizeField->get_held_number() >= 8 )
            {
                load_font( storedFontFileNames[FONT_TTF], fontSizeField->get_held_number() );
            }
        }
        if( loadResourceButton->is_clicked() )
        {
            std::string newFontFile = GPE_GetOpenFileName("Load In Custom Font...","",MAIN_GUI_SETTINGS->fileOpenFontDir );
            if( (int)newFontFile.size() > 3)
            {
                load_font( newFontFile, fontSizeField->get_held_number() );
            }
        }
        else if( confirmResourceButton->is_clicked() )
        {
            save_resource();
        }
        else if( cancelResourceButton->is_clicked() )
        {
            if( GPE_Display_Basic_Prompt("Are you sure you will like to reverse changes?","This will load in data from save-file!", true )== DISPLAY_QUERY_YES )
            {
                resourcePostProcessed = false;
                preprocess_self();
            }
        }
    }
}

bool fontResource::render_held_font( int xPos, int yPos, std::string textureText, GPE_Color * textColor,int hAlign,int vAlign, float renderAngle, float renderScale, int renderAlpha  )
{
    if( fontInEditor!=NULL )
    {
        return fontInEditor->render_text_special( xPos, yPos, textureText, textColor, hAlign, vAlign, renderAngle, renderScale, renderAlpha );
    }
    return false;
}

void fontResource::render_self(GPE_Rect * viewedSpace,GPE_Rect *cam )
{
    viewedSpace = GPE_find_camera(viewedSpace);
    cam = GPE_find_camera(cam);
    if( cam!=NULL && viewedSpace!=NULL  )
    {
        if(fontTypeButtonController!=NULL)
        {
            gcanvas->render_vertical_line_color( 0,0,viewedSpace->h,GPE_MAIN_THEME->Program_Header_Color );
        }
        if( fontInEditor!=NULL)
        {
            gfs->render_text( GENERAL_GPE_GUI_PADDING,GENERAL_GPE_GUI_PADDING,"Font Preview: "+get_short_filename(storedFontFileNames[FONT_TTF],true)+" | "+fontFamilyName,GPE_MAIN_THEME->Main_Box_Font_Color,FONT_LABEL,FA_LEFT,FA_TOP);
            gfs->render_text( GENERAL_GPE_GUI_PADDING,GENERAL_GPE_GUI_PADDING+32,fontPreviewTextField->get_string(),GPE_MAIN_THEME->Main_Box_Font_Color,fontInEditor,FA_LEFT,FA_TOP);
        }
        else
        {
            gfs->render_text( GENERAL_GPE_GUI_PADDING,GENERAL_GPE_GUI_PADDING,"Please Select A Font",GPE_MAIN_THEME->Main_Box_Font_Color,FONT_LABEL,FA_LEFT,FA_TOP);
        }
        for( int i = FONT_FILE_TYPES-1; i >=0; i--)
        {
            if( storedFontFileNames[i].size()> 3)
            {
                gfs->render_text( viewedSpace->w-GENERAL_GPE_GUI_PADDING*2,viewedSpace->h-GENERAL_GPE_GUI_PADDING-GPE_AVERAGE_LINE_HEIGHT*i,SUPPORTED_FONT_EXT[i]+" is used",GPE_MAIN_THEME->Main_Suggestion_Font_Color,GPE_DEFAULT_FONT,FA_RIGHT,FA_BOTTOM);
            }
            else
            {
                gfs->render_text( viewedSpace->w-GENERAL_GPE_GUI_PADDING*2,viewedSpace->h-GENERAL_GPE_GUI_PADDING-GPE_AVERAGE_LINE_HEIGHT*i,SUPPORTED_FONT_EXT[i]+" not used",GPE_MAIN_THEME->Main_Error_Font_Color,GPE_DEFAULT_FONT,FA_RIGHT,FA_BOTTOM);
            }
        }
    }
}

void fontResource::save_resource(std::string alternatePath, int backupId)
{
    if( GPE_LOADER != NULL )
    {
        GPE_LOADER->update_submessages( "Saving Font", resourceName );
    }

    bool usingAltSaveSource = false;
    std::string newFileOut ="";
    std::string soughtDir = get_path_from_file(alternatePath);
    if( path_exists(soughtDir) )
    {
        newFileOut = alternatePath;
        usingAltSaveSource= true;
    }
    else
    {
        soughtDir = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/";
        newFileOut = soughtDir + resourceName+".gpf";
    }
    std::ofstream newSaveDataFile( newFileOut.c_str() );
    //If the font file could be saved
    if( !newSaveDataFile.fail() && newSaveDataFile.is_open() )
    {
        write_header_on_file(&newSaveDataFile);
        if( fontSizeField!=NULL)
        {
            newSaveDataFile << "FontSize=" << std::max(8,(int)fontSizeField->get_held_number() )<< "\n";
        }
        else
        {
            newSaveDataFile << "FontSize=12\n";
        }

        std::string resFileLocation = "";
        std::string resFileCopySrc;
        std::string resFileCopyDest;
        for( int i = 0; i < FONT_FILE_TYPES; i++)
        {
            if( (int)storedFontFileNames[i].size() > 3)
            {
                resFileLocation = storedFontFileNames[i];
                newSaveDataFile << SUPPORTED_FONT_EXT[i]+"_File=" << resFileLocation <<"\n";
                if( (int)resFileLocation.size() > 0 && usingAltSaveSource )
                {
                    resFileCopySrc = file_to_dir(parentProjectName)+"/gpe_project/resources/fonts/"+resFileLocation;
                    resFileCopyDest = soughtDir+resFileLocation;
                    if( file_exists(resFileCopyDest) )
                    {
                        /*
                        if( GPE_Display_Basic_Prompt("[WARNING]Font File Already exists?","Are you sure you will like to overwrite your ["+resFileLocation+"] font file? This action is irreversible!")==DISPLAY_QUERY_YES)
                        {
                            copy_file(resFileCopySrc,resFileCopyDest);
                        }
                        */
                    }
                    else
                    {
                        copy_file(resFileCopySrc,resFileCopyDest);
                    }
                }
            }
        }

        if( fontTypeButtonController!=NULL)
        {
            newSaveDataFile << "FontType=" <<fontTypeButtonController->get_selected_id() << "\n";
        }
        else
        {
            newSaveDataFile << "FontType=0\n";
        }
        if(fontPreviewTextField!=NULL)
        {
            newSaveDataFile << "PreviewText=" <<fontPreviewTextField->get_string() << "\n";
        }
        newSaveDataFile.close();
        if( !usingAltSaveSource)
        {
            isModified = false;
        }
        if( GPE_LOADER != NULL )
        {
            GPE_LOADER->update_submessages( "Font Successfully Saved!", resourceName );
        }
        return;
    }

    GPE_Main_Logs->log_general_error("Unable to save file ["+newFileOut+"]");
    if( GPE_LOADER != NULL )
    {
        GPE_LOADER->update_submessages( "Font Unable to  Save!", resourceName );
    }
}

bool fontResource::write_data_into_projectfile(std::ofstream * fileTarget, int nestedFoldersIn)
{
    if( fileTarget!=NULL)
    {
        if( fileTarget->is_open() )
        {
            std::string nestedTabsStr = generate_tabs( nestedFoldersIn );
            *fileTarget << nestedTabsStr << "Font=" << resourceName << "," << get_global_rid() << ",";

            *fileTarget << "\n";
            //save_resource();
            return true;
        }
    }
    return false;
}

<commit_msg>Delete font_resource.cpp<commit_after><|endoftext|>